Notify user when a date is near

﹥>﹥吖頭↗ 提交于 2020-08-22 19:10:41

问题


I'm currently working on an Android app that uses several Firebase functions. In the Realtime Database I have a date (the date a book is due) and I need to notify the user when that date is near (say, 1 day before the date in the database). Firebase cloud functions doesn't seem to have a specific trigger to do this, as nothing in the database is changing.

I have seen this thread, which can set an alarm/notification for a future date, but I don't know how to stop it once it's been set; I need to be able to cancel the notification if they return the book. This does trigger a change in the database, so I would have an event to use to cancel it, if there was a way to do so.

Is this the best way to do this, or is there a way to implement it using Firebase? And if this is the way to go, how would I cancel a scheduled notification?


回答1:


Coming from the Reddit post you made, use a Job Scheduling tool like JobScheduler (API 21+), Firebase JobDispatcher (API 9+) or Evernote's Android Job (API 14+ but no Google Play Services required).

Since your Firebase Realtime DB is available locally, you have the date (and possibly the time) of when you want to show the notification. One of the job schedulers can simply run a Job which shows a notification, no internet or no server required.

Also, Job scheduling is recommended because, with Android Oreo & above (26+), background tasks have more restrictions on execution.




回答2:


If you are comfortable using Python, then read this post ->

How to Schedule (Cron) Jobs with Cloud Functions for Firebase to create some Firebase cloud functions

My suggestion would be to use the daily-tick function to scan through your Firebase realtime database to retrieve all the books that are "due the next day's date" and issue notifications to them.

It should meet your requirement in a pretty straightforward way. Alternatively, you may try a different method as suggested in the Firebase video here Timing Cloud Functions for Firebase using an HTTP Trigger and Cron - Firecasts

Let me know if neither of these meet your requirements. And what am I missing. I will be glad to recommend a better alternative based on your feedback




回答3:


You can easily cancel the alarm with alarmManager.cancel(pendingIntent). Note that you must provide the same PendingIntent. For more information see How to cancel alarm from AlarmManager. I think this will solve your problem.




回答4:


I have a similar use case, and in my code all triggering is done on the device only once the data snapshot has been updated. I have solved it in the following way:

  1. I have a listener to my database snapshot .addSnapshotListener(new EventListener<QuerySnapshot>()
  2. Once the entries have been retrieved, I set up an alarm for the required dates.
  3. If an entry has been changed (returned in your case), the same snapshot listener is triggered again, loops through entries and cancels alarms.

Code-wise your main activity or service could have something like this:

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

And your broadcast receiver that reacts on the trigger:

public class ItemBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        context.startActivity(intent); // example, add necessary reaction
    }
}


来源:https://stackoverflow.com/questions/47252076/notify-user-when-a-date-is-near

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!