Search code examples
androidfirebaseandroid-sqlitefirebase-notifications

Unable to insert record into SQLite Database from Firebase Message Service when app is in background or closed state


I am trying out Firebase Notifications. I was able to get the Notification to work properly using this documentation. The message was received and I was able to send a notification to the Notification Bar from within the MyFirebaseMessagingService service class. This happens even when the app is in background or closed.

What I need is to collect the data sent in the notification and insert it into an SQLite database. The code I wrote works fine if the app is in foreground, but it does not work if it is closed or in background. Here is what I wrote for the insert.

DbHelper dbh=new DbHelper(this,"sample.sqlite",null,1);
SQLiteDatabase sdb=dbh.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put("id","1");
cv.put("name","testname");
sdb.insert("test",null,cv);
sdb.close();
dbh.close();

Appreciate any help with this. Thanks in advance.

<service android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<service android:name=".MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

public class MyFirebaseMessagingService extends FirebaseMessagingService
{
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        //Displaying data in log
        //It is optional
        Log.i("Tag","inside message" );
        Log.i(StaticInfo.INFO, "From: " + remoteMessage.getFrom());
        Log.i(StaticInfo.INFO, "Notification Message Title  : " + remoteMessage.getNotification().getTitle());
        Log.i(StaticInfo.INFO, "Notification Message Body   : " + remoteMessage.getNotification().getBody());

        insertPromotion();
        sendNotification(remoteMessage.getNotification().getBody());
    }

    private void sendNotification(String messageBody) 
    {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Firebase Push Notification")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0, notificationBuilder.build());
    }

    private void insertPromotion() 
    {
        DbHelper dbh = new DbHelper(this, "sample.sqlite", null, 1);
        SQLiteDatabase sdb = dbh.getWritableDatabase();
        ContentValues cv=new ContentValues();
        cv.put("id","1");
        cv.put("name","testname");
        sdb.insert("test", null, cv);
        sdb.close();
        dbh.close();

        Log.i("Tag","db closed");
    }

}

Solution

  • Notifications will be delivered to your app's onMessageReceived only when the app is in the foreground. When your app is backgrounded or not running, the system will handle the notification and display it in the system tray.

    The Firebase documentation explains it as:

    Notification message - FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages have a predefined set of user-visible keys.

    Data message - Client app is responsible for processing data messages. Data messages have only custom key-value pairs.

    Since you want your code to always be invoked, you'll need to send data messages. You cannot send data messages from the Firebase Console. But if you already send messages from an app server, the process for sending data messages and notification messages is the same there. The only difference is in the JSON structure, where a data messages doesn't have a notification object. From the documentation on data messages

    {
       "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
       "data" : {
         "Nick" : "Mario",
         "body" : "great match!",
         "Room" : "PortugalVSDenmark"
       },
    }