How to implement a "local first" Mobile app storage
I'm trying to learn more about React Native and wanted to create a small habit tracking app. While the details are not that important for this question, one thing that I want to ensure is a local experience even when internet is not available, however all data should be saved in a DB as well. Also, you can have Habits for multiple people, meaning 2 people can edit the same habit while being on/offline.
Basically, I would need a way to sync the phone's local storage with my DB. However, while thinking about it I found some gotchas that I don't have a happy solution for.
1. First of all, how does it work. E.g. when the user adds a habit, is it firstly saved locally then synced. Is it saved to the DB and locally at the same time if there is a internet connection? Or something else entirely?
2. Since multiple people can edit the same thing while offline, what happens when they get back online? Does one override the other? Do they merge? - probably something I have to decide myself, but I'm still unsure of the implementation
3. Do I need Real-time data if someone can edit a Habit I'm currently browsing?
4. there is probably more I can't think of but I'm open for suggestions
4 Replies
pretty sure you can embed MySql into frontend app
and what i would do in ur case is to store the whole state on the client side
and only send what is needed back and forth from the server
so that way everything that is core and central (habit tracking) is actually stored on app
and u essentially use git like messages between server and client to add or change or display data/analytics
and you store it as a blockchain ig where each action by the user is synced with server
this is what snapchat and whatsapp do where the server only routes messages and doesnt store them which is why u can access chat
so 1: data is saved on device and then it is put into a queue if it is shared with other people to then be sent out via something like xmpp when the other devices are online, you then delete this from server
2. do a blockchain and look into concurrent editing of text files also rethink the idea and utility of 2 people changing the exact same piece of data because for habit tracking that is slightly strange.
3. save on edit so when they commit the habit will change because otherwise with the system i talked about before (what whatsapp uses) that is just an obscene amount of data to transfer - dont build google docs!!!
From observing the behaviors from some popular local-first apps (AnyType, Obsidian, Notion?), a common approach is to:
1. Save the data locally if no internet connection
2. If connection is available, sync to central server and distribute changes to all other users
3. Pull changes from central server to update local storage with other users' changes
The data structure used in these collaborative apps is most likely CRDT (conflict-free replicated data type), which replicates the same data to all users and allows them to update their copy of the data concurrently. The key idea is that all the replicated data will eventually merge together in a central location, and redistributed back to all users.
If you just want to get something working, I would suggest using a library / platform like Liveblocks. They can handle the infrastructure and backend logic for you for FREE up until 100 monthly active users.
Here's an example of a collaborative todo list in React Native
Collaborative To-do List | Liveblocks Example
This example shows how to build a collaborative to-do list with Liveblocks and React Native.
However, creating your own solution is a great learning opportunity too. In that case, you might find RxDB useful, since it is designed specifically for local-first apps and data syncing with your backend.
RxDB - JavaScript Database | RxDB - JavaScript Database
RxDB is a fast, local-first NoSQL-database for JavaScript Applications like Websites, hybrid Apps, Electron-Apps, Progressive Web Apps and Node.js
yup CRTD is needed for concurrent modification but you actually store on CLIENT and send updates to server for efficiency
likely with XMPP as a transport layer