I was trying listen for a change in firebase firestore collection, after the app is closed. For that I have written the following code:
FirebaseFirestore.getInstance().collection("demo").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
//show a notification to user
...
...
Toast.makeText(MainActivity.this, "collection modified", Toast.LENGTH_SHORT).show();
}
});
It works when the app is in background (pressed backbutton
to exit app, but app is available on recent screen) but when I clear the app from recent screen, the code stops working.
How can I listen for firebase event even after the app is killed?
Edit:
I tried to use two approaches, but as soon as the app get swiped from recents screen both of these approaches stop working:
- Using
Alarm Manager
. Following is the code for this implementation:
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
FirebaseFirestore.getInstance().collection("demo").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
Toast.makeText(context, "collection modified", Toast.LENGTH_LONG).show();
}
});
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startFirebaseTesting();
}
});
}
private void startFirebaseTesting() {
Intent in = new Intent(this, FirebaseService.class);
in.setAction("com.example.this.app");
in.addCategory("android.intent.category.DEFAULT");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 4, in, PendingIntent.FLAG_ONE_SHOT|PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000*5, pendingIntent);
} else
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000*5, pendingIntent);
}
}
AndroidManifest.xml
<application>
...
...
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.this.app"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
...
...
</application>
- Adnan Arshad's answer to this question
Both of these solution don't work on MotoG5s plus (Oreo) and Samsung A50 (Android 10).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…