I have collection called tasks
and each document contains fields like
updatedAt
name
isDone
Instead of querying all docs all the time, I get the latest updatedAt
from cache and build the query using greaterThan:latestUpdatedAt
. But I feel this logic can horribly go wrong in this scenario.
Consider a user using this app from his phone and web also.
- Let’s consider current
updatedAT
on user’s phone is2023-5-20 08:01:00
- User creates task
T1
onweb
which immediately synced to server withupdatedAt
being2023-5-20 09:01:00
- User creates a task
T2
on phone but at the moment phone has no internet connection - When user gets connection back on his phone
T2
will sync to server withupdatedAt
being2023-5-20 09:02:00
Now the problem is I have no idea how the firestore internal sync logic works so if sync of T2
happens before get tasks query greaterThan:latestUpdatedAt
then my latestUpdatedAt
becomes 2023-5-20 09:02:00
and I will never get task T1
which is created on web. This is just a speculation and I am not sure about but without the confirmation I am bit skeptical to push the app to production.
This idea of reducing reads is inspired by an article written by firebase expert Alex Mamo but I am not sure whether he is aware of this issue or not.
2
Answers
You have to update
latestUpdatedAt
when you GET data and not when you PUSH data to Firebase.You need a local date to save the last sync and a remote one to track updates, when the remote date is after the local date you have to fetch data from the server and update your local date with the new one.
with this approach, your scenario is:
localUpdateAt
on the phone is2023-5-20 08:01:00
andremoteUpdateAt
is2023-5-20 08:01:00
T1
on the web which immediately synced to the server withremoteUpdatedAt
being2023-5-20 09:01:00
T2
on the phone but at the moment phone has no internet connectionT2
will sync to the server withremoteUpdatedAt
being2023-5-20 09:02:00
localUpdateAt
on the phone is still2023-5-20 08:01:00
that is beforeremoteUpdatedAt
get data from the server withgreaterThan:localUpdateAt
Usually, I create a collection specific to store the last updates for others’ collections.
I hope can be helpful for you.
How about saving
lastSyncTime
to local SharePreference only if the connection state of the Firebase is online?https://firebase.google.com/docs/database/flutter/offline-capabilities#section-connection-state
Scenario:
lastSyncTime
=2023-5-20 07:01:00updateAt
lastSyncTime
no change, T2‘supdateAt
is not enable because server is offlinelastSyncTime
=2023-5-20 09:03:00, same as T2‘supdateAt