我正在开发聊天应用,并且正在使用Firebase Cloud Messaging进行通知。我发现最好将通知(通知信息)保存在本地数据库(即Room)中,这样可以帮助我处理徽章计数和清除特定的聊天通知。
步骤:
我在Google上进行了搜索,但唯一的解决方案是使用LifecycleService,但出于通知目的,我需要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());}
}
我正在开发聊天应用,并且正在使用Firebase Cloud Messaging进行通知。我发现最好将通知(通知信息)保存在本地数据库(例如Room)中,这样可以帮助我...
我在回答自己的问题,只是为了展示我的替代解决方法。我相信liveDataObserver对我来说仍然是最好的方法,但是直到有人为我提供在FirebaseMessagingService中获得LivecycleOwner的解决方案来帮助我之前,我将为[insert() and my getAll()