日期临近

时间:2017-11-12 17:59:15

标签: android firebase-realtime-database push-notification firebase-cloud-messaging

我目前正在开发使用多个Firebase功能的Android应用。在实时数据库中,我有一个日期(一本书到期的日期),我需要在该日期临近时(例如,数据库中的日期前一天)通知用户。 Firebase云功能似乎没有特定的触发器来执行此操作,因为数据库中没有任何内容正在发生变化。

我看过this个帖子,可以为将来的某个日期设置闹钟/通知,但我知道如果设置它就停止播放;如果他们退回书,我需要能够取消通知。这确实触发了数据库中的更改,因此如果有办法,我会使用一个事件来取消它。

这是执行此操作的最佳方式,还是有办法使用Firebase实现它?如果这是要走的路,我该如何取消预定的通知?

4 个答案:

答案 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)

我有一个类似的用例,在我的代码中,只有在数据快照更新后,才会在设备上完成所有触发。我已通过以下方式解决了这个问题:

  1. 我有一个监听我的数据库快照.addSnapshotListener(new EventListener<QuerySnapshot>()
  2. 检索完条目后,我会为所需日期设置闹钟。
  3. 如果条目已更改(在您的情况下返回),则会再次触发相同的快照侦听器,循环条目并取消警报。
  4. 代码方面,您的主要活动或服务可能包含以下内容:

    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
        }
    }