Introduction
At YLD we have been doing some work with offline-first applications and, with the release of Service Workers, a major step has been taken in building these kind of applications in the browser. We have also been using CouchDB and PouchDB to access data while the Application is offline. At some point, we started to wonder if we could do the same on native mobile apps while using React Native.
The problem
Can we achieve an offline-first experience using React Native? Can we store data locally? Can we sync data between multiple devices?
The solution
For this purpose, we built a simple collaborative application where users can add or remove notes. You can find it here.
React Native
The entry points for a react native application are index.ios.js and index.android.js, for iOS and Android devices respectively. However, for this particular example, we focused on iOS only.
- DocsApp.js is the main component, also where the main state is kept.
- Docs.js is the documents list.
- DocForm.js is used to add new documents.
PouchDB
Luckily PouchDB exists and we can take advantage of its replication system to store data locally when offline and synchronise it with a remote CouchDB database once the application is back online.
Setup the databases
We can either create/use a local database, or use PouchDB as a client to a remote CouchDB instance.
Replicate the data from local store to remote CouchDB and vice-versa
The PouchDB API provides a method for bidirectional data replication. It accepts the live option, so that all changes continue to be replicated, and the retry option, to attempt replications if the application goes offline.
Persisting the data
The data is persisted in the local PouchDB and replicated when possible.
Subscribe to database changes
We can also subscribe to the changes feed so that after receiving a change — either from the remote server or the local user — the UI is updated, either by creating, updating or deleting a document.
Ok, now we are syncing the data, but what about other assets, such as images?
React Native provides a native component to display images, with some functionality that can help us.
The source attribute is self-explanatory and the defaultSource is used to display a static image when loading the source.
This component will cache the image after the first download, so further requests of the same image won’t trigger a network request.
In the PoC application we built, we are only generating 3 different images. After that, we are using the same URLs so that we can see the application using the cached images.
Conclusion
Building a React Native offline-first data-driven application using PouchDB and CouchDB is, in many ways, similar to the way you would build a web app using React. By using PouchDB you can access a local store that, once there is network connectivity, syncs data to and from a remote CouchDB service.