我目前正在开发使用多个Firebase功能的Android应用。在实时数据库中,我有一个日期(一本书到期的日期),我需要在该日期临近时(例如,数据库中的日期前一天)通知用户。 Firebase云功能似乎没有特定的触发器来执行此操作,因为数据库中没有任何内容正在发生变化。
我看过this个帖子,可以为将来的某个日期设置闹钟/通知,但我知道如果设置它就停止播放;如果他们退回书,我需要能够取消通知。这确实触发了数据库中的更改,因此如果有办法,我会使用一个事件来取消它。
这是执行此操作的最佳方式,还是有办法使用Firebase实现它?如果这是要走的路,我该如何取消预定的通知?
答案 0 :(得分:8)
根据您制作的Reddit帖子,使用Job {JobScheduler
(API 21+),Firebase JobDispatcher
(API 9+)或Evernote's Android Job等作业调度工具(API 14+但不是需要Google Play服务)。
由于Firebase Realtime DB在本地可用,因此您可以获得要显示通知的日期(可能还有时间)。其中一个作业调度程序可以简单地运行一个显示通知,无需互联网或无需服务器的作业。
此外,建议使用作业调度,因为Android Oreo&在上面(26+),后台任务执行时more restrictions。
答案 1 :(得分:1)
如果您习惯使用Python,请阅读此文章 - >
How to Schedule (Cron) Jobs with Cloud Functions for Firebase 创建一些Firebase云功能
我的建议是使用daily-tick
功能扫描您的Firebase实时数据库,以检索所有预定的日期"以及第二天的日期"并向他们发出通知。
它应该以非常简单的方式满足您的要求。或者,您可以尝试使用Firebase视频Timing Cloud Functions for Firebase using an HTTP Trigger and Cron - Firecasts
中建议的其他方法如果这些都不符合您的要求,请告诉我。我错过了什么。我很乐意根据您的反馈推荐更好的替代方案
答案 2 :(得分:0)
您可以使用alarmManager.cancel(pendingIntent)
轻松取消闹钟。请注意,您必须提供相同的PendingIntent
。有关更多信息,请参阅How to cancel alarm from AlarmManager。
我认为这将解决您的问题。
答案 3 :(得分:0)
我有一个类似的用例,在我的代码中,只有在数据快照更新后,才会在设备上完成所有触发。我已通过以下方式解决了这个问题:
.addSnapshotListener(new EventListener<QuerySnapshot>()
代码方面,您的主要活动或服务可能包含以下内容:
db.collection("items").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if(e==null) {
ArrayList<Item> itemsList = new ArrayList<>();
itemsList.addAll(documentSnapshots.toObjects(Item.class));
for(Item item:itemsList){
if(item.isReturned()){
cancelAlarm(item);
}
else {
setAlarm(item);
}
}
} else {
// error handling
}
}
});
Intent intent;
PendingIntent pendingIntent;
final AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
public void setAlarm(Item item){
intent = new Intent(context, ItemBroadcastReceiver.class).putExtra("ID", item.getUuid());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, item.getUniqueIntegerCode(), intent, 0);
am.set(AlarmManager.RTC_WAKEUP, item.getDateTimeDue().minusDays(1), pendingIntent);
}
public void cancelAlarm(Item item) {
if(intent != null && pendingIntent != null){
am.cancel(pendingIntent);
/// if item needs to be saved, add your firestore set() routine
}
}
你的广播接收器对触发器作出反应:
public class ItemBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startActivity(intent); // example, add necessary reaction
}
}