有没有办法在FirebaseMessagingService中获得生命周期所有者



我正在开发一款聊天应用,并使用 Firebase 云消息传递功能发送通知。 我发现最好将我的通知(通知信息(保存在本地数据库(即 Room(中,以便它可以帮助我处理徽章计数和清除特定聊天通知。

步骤:

  1. 设置我的 FirebaseMessagingService 并经过测试。(成功获取我的通知(;
  2. 设置房间数据库并测试插入和获取所有数据(实时数据((工作正常(;
  3. 我想观察MyFirebaseMessagingService中的实时数据,但要做到这一点,我需要一个LivecycleOwner,我不知道从哪里得到它。

我在谷歌上搜索,但唯一的解决方案是使用生命周期服务,但我需要FirebaseMessagingService来通知我。

这是我的代码:

//Room Database class
private static volatile LocalDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService taskExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static LocalDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (RoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
LocalDatabase.class, "local_database")
.build();
}
}
}
return INSTANCE;
}
public abstract  NotificationDao dao();


//DAO interface
@Insert
void insert(NotificationEntity notificationEntity);
@Query("DELETE FROM notificationentity WHERE trade_id = :tradeId")
int clearByTrade(String  tradeId);
@Query("SELECT * FROM notificationentity")
LiveData<List<NotificationEntity>> getAll();


//Repository class{}
private LiveData<List<NotificationEntity>> listLiveData;
public Repository() {
firestore = FirebaseFirestore.getInstance();
storage = FirebaseStorage.getInstance();
}
public Repository(Application application) {
LocalDatabase localDb = LocalDatabase.getDatabase(application);
dao = localDb.dao();
listLiveData = dao.getAll();
}
...
public void saveNotificationInfo(@NonNull NotificationEntity entity){
LocalDatabase.taskExecutor.execute(() -> {
try {
dao.insert(entity);
H.debug("NotificationData saved in local db");
}catch (Exception e){
H.debug("Failed to save NotificationData in local db: "+e.getMessage());
}
});
}
public LiveData<List<NotificationEntity>> getNotifications(){return listLiveData;}
public void clearNotificationInf(@NonNull String tradeId){
LocalDatabase.taskExecutor.execute(() -> {
try {
H.debug("trying to delete rows for id :"+tradeId+"...");
int n = dao.clearByTrade(tradeId);
H.debug("Cleared: "+n+" notification info from localDatabase");
}catch (Exception e){
H.debug("Failed clear NotificationData in local db: "+e.getMessage());
}
});
}


//ViewModel class{}
private Repository rep;
private LiveData<List<NotificationEntity>> list;
public VModel(@NonNull Application application) {
super(application);
rep = new Repository(application);
list = rep.getNotifications();
}
public void saveNotificationInfo(Context context, @NonNull NotificationEntity entity){
rep.saveNotificationInfo(entity);
}
public LiveData<List<NotificationEntity>> getNotifications(){
return rep.getNotifications();
}
public void clearNotificationInf(Context context, @NonNull String tradeId){
rep.clearNotificationInf(tradeId);
}


and finally the FiebaseMessagingService class{}
private static final String TAG = "MyFireBaseService";
private static final int SUMMARY_ID = 999;
private SoundManager sm;
private Context context;
private  final String  GROUP_KEY = "com.opendev.xpresso.group_xpresso_group_key";
private Repository rep;
private NotificationDao dao;
@Override
public void onCreate() {
super.onCreate();
context = this;
rep = new Repository();
}
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
@Override
public void onNewToken(@NonNull String s) {
super.onNewToken(s);
}
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
H.debug("OnMessageReceived...");
try {
Map<String, String> data = remoteMessage.getData();
if (Objects.requireNonNull(data.get("purpose")).equals("notify_message")) {
String ChatId
if ((chatId=data.get("chatId"))==null){
H.debug("onMessageReceived: tradeId null! Aborting...");
return;
}
FirebaseFirestore db = FirebaseFirestore.getInstance();
Task<DocumentSnapshot> tradeTask = db.collection("activeTrades").document(chatTask).get();
Task<DocumentSnapshot> userTask = db.collection("users")
.document(FirebaseAuth.getInstance().getCurrentUser().getUid()).get();
Tasks.whenAllSuccess(chatTask, userTask).addOnSuccessListener(objects -> {
if (!((DocumentSnapshot)objects.get(0)).exists() || !((DocumentSnapshot)objects.get(1)).exists()){
H.debug("OnMessageReceived: querying data failed:  NOT EXISTS");
return;
}
Chat chat = ((DocumentSnapshot)objects.get(0)).toObject(Trade.class);
MainActivity.USER = ((DocumentSnapshot)objects.get(1)).toObject(User.class);

//Now we got all the needed info we cant process the notification
//Saving the notification locally and updating badge count
//then notify for all the notification in localDatabase
NotificationEntity entity = new NotificationEntity();
entity.setNotificationId(getNextNotificationId());
entity.setTradeId(tradeId);
entity.setChanelId(context.getResources().getString(R.string.channel_id));
entity.setTitle(data.get("title"));
entity.setMessage(data.get("message"));
entity.setPriority(NotificationCompat.PRIORITY_HIGH);
entity.setCategory(NotificationCompat.CATEGORY_MESSAGE);
rep.saveNotificationInfo(entity);
rep.getNotifications().observe(HOW_TO_GET_THE_LIVECYCLE_OWNER, new Observer<List<NotificationEntity>>() {
@Override
public void onChanged(List<NotificationEntity> notificationEntities) {
//
}
});
}).addOnFailureListener(e -> H.debug("OnMessageReceived: querying data failed:  "+e.getMessage()));
}
}catch (Exception e){H.debug(e.getMessage());}
}

已更新, 因为不建议在 FirebaseMessagingService 中使用 LiveData 对象,因为 FirebaseMessagingService 不是 Android 活动生命周期的一部分,因此没有生命周期所有者。与其尝试在FirebaseMessagingService中使用LiveData,不如考虑使用不同的方法来处理徽章计数和清除特定的聊天通知。

所以我使用广播接收器来接收通知。然后,我可以在我的FirebaseMessagingService中设置广播接收器,它将接收通知并更新本地房间数据库中的徽章计数。

我为此创建了一个广播接收器,在 onReceive 方法中,我将 Intent 发送到服务并处理服务中的标志逻辑。

我回答我自己的问题只是为了展示我的替代解决方法。 我相信liveDataObserver对我来说仍然是最好的方法,但在有人帮助我为我提供在FirebaseMessagingService中获得LivecycleOwner的解决方案之前,我将使用自定义侦听器作为我的insert() and my getAll()

喜欢关注

public interface RoomInsertListener{
void onInsert();
}
public interface RoomGetListener{
void onGet(List<NotificationEntity> list);
}

然后在FirebaseMessagingService中使用它,如下所示

NotificationEntity entity = new NotificationEntity();
entity.setNotificationId(getNextNotificationId());
entity.setTradeId(tradeId);
entity.setChanelId(context.getResources().getString(R.string.channel_id));
entity.setTitle(data.get("title"));
entity.setMessage(data.get("message"));
entity.setPriority(NotificationCompat.PRIORITY_HIGH);
entity.setCategory(NotificationCompat.CATEGORY_MESSAGE);
rep.saveNotificationInfo(entity, () -> rep.getNotifications(list -> {
ShortcutBadger.applyCount(context, list.size());
H.debug(list.size()+" notifications in Database: applied badge count...");
for (NotificationEntity e:list){
H.debug("id:"+e.getNotificationId()+" trade: "+e.getTradeId());
}
}));

最新更新