I am looking at building an offline first React Native Expo app that automatically pushes data to an API when the device gets a connection. However I am struggling to see how if this is possible within Expo and need some guidance.
The app will need to store data from an API for offline use (presumably on first load, which will then be used to populate fields in a form). The form needs to work offline, with the input data stored on the device until it receives a new connection. At that point the app should push the data to an API (whilst the app is in the background). So I need to do multiple things:
Automatically download and store data from an API on first launch.
Store input data - from form fields whilst offline.
Background sync - Upload this user form data when a new connection is received, regardless of whether the app is running in the background or not.
Work on Android and iOS devices.
I have been looking at redux-offline, but unsure if it still supported and/or will satisfy all four requirements?
There is also redux-persist but I can't see how this satisfies the background sync?
Thanks for any help/guidance!
From my point of view, redux-persist is less opinionated compared to redux-offline. I pick redux-persist with useNetInfo hook to listen to network availability.
1. Automatically download and store data from an API on first launch.
When app launch, query initial data and dispatch to redux store and synced automatically to local storage by redux-persist
2. Store input data - from form fields whilst offline.
With useNetInfo, the app can detect network connectivity status, when not connected, dispatch to the redux store with a flag to indicate offline unsynched data.
You need to write a network connectivity listener which is executed when the network state changes and continuously track unsynched data and sync with the database when available and purge those temporary data like form values.
3. Background app sync
Expo SDK provides API https://docs.expo.dev/versions/latest/sdk/background-fetch/
to run continuously a background task at a certain time threshold.
You can sync offline data when the network returns back while the app is background.
Disclaimer: Background tasks run outside of React componentS tree. You can't access redux store data through the react-redux's store component or hooks based API.
redux-persist saves data with Async Storage and you need to directly access data as below.
AsyncStorage.getItem("persist:[REDUCER_CONTAIN_INTERESTED_DATA]")
This seems to be an issue with server state with a client cache. Looks like an ideal case for react-query to solve.
Automatically download and store data from an API on first launch.
This should be taken care of by query prefetching
Store input data - from form fields whilst offline.
Probably needs client state(redux/Zustand etc) for managing state with unverified fields. For storing submitted forms, react-query supports offline caching of 'mutations'.
Background sync - Upload this user form data when a new connection is received, regardless of whether the app is running in the background or not.
Work on Android and iOS devices.
See above.
Related
I'm working on an app similar to Trello in that it needs to pull data from the server as soon as it's added by other users. There is no need to send data back using the same channel, so Server-Sent Events (unidirectional) push technology seems more appropriate to use here than WebSocket.
The App is a cross-platform React Native (expo managed) project that displays a list of items from the server with options to add, update, and delete. For now, it will work only while an internet connection is available.
Locally, data will be stored in a redux store (RTK Toolkit). The way the app will keep the redux store up to date is: Establish an open connection to the server using SSE (Server-Sent Events) and listen for events. Use RTK Query to fetch, update, and delete data. On receiving an SSE event (an event with information that new data is available on the server, updates were done by someone else), the app will clear the local RTK Query cache and fetch the whole data set again from the server.
There are several concerning issues that could affect the performance and usability:
Downloading the entire data set in response to any type of update event (new/updated/deleted item by another user) will retrieve the entire list, which may contain many items with nested ones. It doesn't seem to be an effective approach. Especially if another user performs multiple minor changes (changes name, persists, changes date, persists, adds description, persists...), this will result in at least 3 update events.
After performing an action on your own, the entire data set will be downloaded. I.e., a user adds a new item, there is a call POST to the server, the server pushes events, and the user gets an event that there is newer data on the server. RTK Query's cache will be reset and a new dataset will be fetched and stored in redux.
I don't have that extensive experience with React Native, so I would like to ask more seasoned veterans if this solution can actually work and how it can be improved.
Many thanks.
Good evening everyone .
I am developing a react native app by interfacing to a database via endpoint (specifically aws).
Now on loading the dashboard I retrieve this data via API , save it in local storage and show it to the user.
Now from the management system, there could be some changes to this data that I show on the app, so what I was interested in knowing was if it was possible to create a sort of listener that calls my API whenever there are changes in the DB. I ask this because I would like to avoid calling the API every time a user lands on the dashboard and I would like to avoid calling the API every XXX minutes if there is no reason (if the data has not changed).
Is there any way to create an event listener? It would also be enough for me to be directed on what exactly to look for.
Thanks in advance for your availability
I am new to react native. I am making a app to support offline. So, I use asyncstorage and redux-persist package. Data is saving offline and data could clean every functions are working fine. So, my question is
How can I detect offline data to be always updated. Could you mention your experience solutions to solve it. I found more questions in google about saving data solution not including update solutions.
Below are what I think.
push notification from Google cloud messaging ( It is ridiculous to let user know push notification on device screen to update data)
Websocket might work on it.( I don't want to build for that in my backend server now)
Saving each reducer store with datetime and check with app is online or offline. If online, it would request from server to get reducer in which has new datetime, if so, I would update my offline data. I am not sure that could cover all. ( In this case, I would create all reducer name and updated datime when device request )
I guess you want your app offline data updated with the online server data. You can use react-native-offline. You can check its doc. When app open it sync can sync data with the server and update. So you app will always update.
I want to know how and when the redux store gets cleared in a react native app. Does it get cleared when the app close? Does it get cleared when the user clear it from running apps? Or does it clear only when I uninstall the app?
Depends. Redux just creates an object (the store) which is kept alive as long as the JavaScript runs (that means, if you close the app, the store object will be deleted and all information lost). However, if you use a persistence layer on top of redux, say, redux-persist, your data will be stored in the persistant storage of the application, which gets cleared once you either uninstall the application or, in the Android case, also when you clear the application data.
All the state stored inside the redux store will be cleared when the App is removed from task manager(clear it from running app). When the app is uninstalled all the data related to the app gets cleared such as the local database, file system etc.
The flow goes like this user->trigger action->reducer takes the action, and previous state and update store->updated state stored in the redux store (only one big javascript object)->provider which makes store available to container->data goes to component->user can view data in the component. It's a unidirectional data flow.
I am designing a web app that fetches data every time a user logs into his/her account. The data is an xml file containing image links and some text. I want this data (after image fetch/load from the actual link) to be stored locally so that every time an user opens the app it doesn't have to load everything from scratch. Locally stored contents should load first, then in the background some network processing shall be done so that the newer data is automatically updated. For storing the data I am planning to use SQLite but is there any other efficient way other than this to do the same ?
How does facebook app do this kind of stuff ? Thank you so much
The Facebook app is not really a web app but rather a native Cocoa Touch app.
If you are really creating a web app, your only option is to use localstorage and fetching new data asynchronously using XMLHTTPRequest.
If – on the other hand – your app is a native app, you’ll most likely want to use Core Data for storage and get incremental updates in a separate thread (or using libdispatch in case you’re only targetting post 4.0 devices) using a separate managed object context which you can then merge to the main thread using mergeChangesFromContextDidSaveNotification:.