Jeremiah Zucker
Jeremiah Zucker

Reputation: 182

Firestore stops updating after losing and regaining an internet connection

I have set up some listeners like so:

deviceListener = db.addSnapshotListener(this::handleDbChange)

When I have a stable internet connection, the handler fires on a data change and allows me to update my application. However, when I lose and regain an internet connection the handler ceases to fire. This doesn't always occur on the first loss of connection, but it always occurs after 2 or 3 drops in my connection.

I have tried removing the listeners and re-adding them when the network changes. Additionally, I tried getting the data directly after the network connection is reestablished:

db.get().add().addOnCompleteListener {
   val snapshot = it.result
   snapshot.toObject(Model::class.java)
}

But, this still serves the stale data. The only way I've found to correct this issue is restarting the app.

If anyone else has encountered this issue, I'd appreciate any insight you may have on how to solve it. FYI, I'm using the com.google.firebase:firebase-firestore:17.0.2 version of the library.

Upvotes: 8

Views: 2299

Answers (2)

Joonsoo
Joonsoo

Reputation: 908

Use device instead of emulator as NicCoe has mentioned. I also suffered from a similar problem for a long time and finally found that Firestore works differently on device and emulator. (FYI, I'm using com.google.firebase:firebase-firestore:17.1.3) Most problems were solved after changing the test environment with the device. One small problem with the device I have found is that Firestore gives empty result several times after regaining an internet connection. And I solved it with this code:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    ...
    mRetryButton.setOnClickListener {
        val pendingIntent = PendingIntent.getActivity(context, 0, Intent(context, ThisActivity::class.java), PendingIntent.FLAG_ONE_SHOT)
        val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent)
        System.exit(0)
    }
    ...
}


fun fetchData() {
    FirebaseFirestore.getInstance().collection("col_name").get()
            .addOnCompleteListener {
                if (it.isSuccessful) {
                    val result = it.result!!
                    if (result.isEmpty && result.metadata.isFromCache) {
                        mRetryButton.visibility = View.VISIBLE
                        return@addOnCompleteListener
                    }
                    var docs = result.documents
                    ...
                } else {
                    Log.d(TAG, "Error getting documents: ", it.getException())
                }
            }
}

Upvotes: 0

NicCoe
NicCoe

Reputation: 419

I know its a late reply, and i'm only a novice here (so I could be wrong), but for anyone else to come across this... it may be a combination of the problem I had:

Firebase Firestore batch command wont commit after regaining connection

And the problem someone else had:

Firestore doesn't immediately start listening to changes when Internet Connection Resumes


In summary:
Ensure you test without an emulator.
If you need live data, turn data persistence off.
And Firestore may use an uncontrollable timer to dictate when it reconnects its listeners after a connection is regained.

Upvotes: 1

Related Questions