4

I'm working on an App that gets data via Firebase messaging, inserts it into SQLite and displays information in the App (if it's visible)

First I have the Firebase service setup in MANIFEST.XML

    <!-- [START firebase_service] -->
    <service
        android:name=".MyHandler">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

Next in MyHandler.java I handle a new message event and call the insert in SQLite helper

public class MyHandler extends FirebaseMessagingService {

SQLActivity dbsrv = new SQLActivity(this);

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    dbsrv.crtMSG("SQ32 ETA 11:25");
    sendNotification("Flight update");
    if (MainActivity.isVisible) {
         MainActivity.mainActivity.SnackNotify("Flight update");
    }

This is the relevant call in my SQLIte helper class

public class SQLActivity extends SQLiteOpenHelper{

public void crtMSG(String sMSG) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(MSGWRXF.MSGH.MSG, sMSG);
    db.insert("MSGH", null, values);
    db.close();
}

Occasionally I get this error, usually it seems when multiple messages are received simultaneously:

"Exception java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed."

Not entirely sure of the Firebase messaging architecture, but it seems like messaging events are firing off inserts so quickly that they don't all complete before the connection gets closed.

This App works absolutely fine whether the App is in foreground, background and closed state when messages arrive one at a time! It also works fine even if the device is switched when it is sent messages, they arrive when it's switched on again

I'm wondering if maybe I could just drop the db.close() in the database insert..?

rangi
  • 361
  • 2
  • 4
  • 21
  • You need to synchronise this method and others which are using instance of database... – Selvin Jan 23 '17 at 20:48
  • Background for Selvin's comment is at this answer: http://stackoverflow.com/a/37562940/4815718 – Bob Snyder Jan 23 '17 at 21:52
  • Thanks people. I had read that post, which led me to think taking out the db.close() might eliminate the issue. I've updated my question above. – rangi Jan 24 '17 at 00:33

2 Answers2

1

I don't see the reason as to why you are saving your data to Sqlite , because Firebase has the capability of Offline . When there's no network , the data can cache it's self. And its the simplest.

Firebase Offline Capability

Lutaaya Huzaifah Idris
  • 3,596
  • 8
  • 38
  • 77
  • OP is not using the Firebase Database, but only Firebase Cloud Messaging. While using FCM + Firebase Database is an acceptable combination, so is using FCM stand-alone. – Frank van Puffelen Jan 23 '17 at 22:03
1

Having changed and run the code under fairly severe test conditions I can confirm that removing the close() from the insert call resolved this issue!

With close() in the insert the App falls over at about 95/100 messages and loses the rest, while without it 100/100 are received and logged in the SQLite database.

I think that this might be because getWritableDatabase() can be called multiple times concurrently from within the message event handling service (activity) without having to be explicitly closed.

I'm happy to be corrected if that is not the case and/or this is a poorly implemented solution

rangi
  • 361
  • 2
  • 4
  • 21