I have a similar use case, and in my code all triggers are executed on the device only after updating the data snapshot. I solved it as follows:
- I have a listener for a database snapshot
.addSnapshotListener(new EventListener<QuerySnapshot>() - After the records were restored, I set an alarm for the required dates.
- If the recording was changed (returned in your case), the same snapshot receiver starts again, iterates through the recordings and cancels the alarms.
According to your core business or service, there might be 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 responds to the trigger:
public class ItemBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { context.startActivity(intent);
source share