mardi 24 mars 2020

Syncing unsent messages from server to client with local db

In an instant messaging app, the users' mobile devices contain a db like SQLite for offline storage, and the server has Postgres for cold storage, and Redis for storing X recent messages.

When a user is offline, I want to be able to sync new messages to their SQLite using the push notification sent to them. And then once they go online, check with the server whether there are some messages that he didn't receive.

How can this be done efficiently?

Example + semi-solution :

When a user is offline, I send FCM pushes to the user with the new messages sent to them. That means, the app can update the local SQLite db with those new messages even if I'm not showing the notification itself (if a user has opted-out from receiving those).

Initially I thought about storing the last time the SQLite was updated and then upon connection establishment (websocket), check and retrieve all the messages (if there were) from that timestamp in server.

But push notifications are something rather unreliable, and FCM can skip messages or send those with a great delay.

For example, imagine we sent messages A, B, C through FCM push, and B is skipped by the FCM for some reason. That means that C's timestamp would be set, and then the server would think "alright, the user has all the messages up until C's timestamp, so no point in sending him anything before that". Thus, B will never get to the user.

I could solve that, by retrieving ALL the messages from the last time the user was online, and then check on their app locally against the SQLite whether I have all those messages stored there. But that seems rather inefficient.

How is this sort of syncing usually done in an efficient manner?

Aucun commentaire:

Enregistrer un commentaire