Android: Linking and syncing Room database to online server database - java

I am developing an app that uses a database to store the data on the server, but I am trying to save some of the data locally, and in the event of no internet connection being established, save new data locally to the device and synchronize any changes to the server when an connection is re-established. What is the best and most efficient way to do this?
I have been looking at Androids Room persistence library and it seems like the logical choice, but I am not sure how it goes about synchronizing changes to/from the local storage database. I have looked at multiple threads and forums for help, but have had no luck so far. Please help.

One way is to build your own sync adapter: https://developer.android.com/training/sync-adapters
You will need to handle most of the sync logic between the client and the server, but that allows you to use any database technology in the server. From the docs:
A sync adapter doesn't automate any data transfer tasks. If you want to download data from a server and store it in a content provider, you have to provide the code that requests the data, downloads it, and inserts it in the provider. Similarly, if you want to send data to a server, you have to read it from a file, database, or provider, and send the necessary upload request. You also have to handle network errors that occur while your data transfer is running.
A sync adapter doesn't automatically handle conflicts between data on the server and data on the device. Also, it doesn't automatically detect if the data on the server is newer than the data on the device, or vice versa. Instead, you have to provide your own algorithms for handling this situation.

Use firestore and enable offline data persistence. https://firebase.google.com/docs/firestore/manage-data/enable-offline

Related

Any way to efficiently sync two databases?

I am planning to make a software which requires two or more databases to be in sync with a main server database ( located on a web server ). Suppose one user have installed my software on more than one computers. Suppose he updates some info on PC-1 then the change should be locally updated and if he is connected with the internet, it should get in sync with the main web server. When he opens the software on PC-2, latest into must be shown there ( assuming he is connected with the internet ).
Now suppose both PC-1 and PC-2 have same data, and both are offline. User deletes the data from PC-1 but don't deletes it from PC-2 ( he assumes it'll get managed automatically ), now when both of the systems go online, the record must be deleted from PC-2 too.
Basically, I am trying to find the database which was most recently updated or modified and sync it with the main database ( on the server ). How can I do it ?
It sounds like you want to synchronize some user data whenever the users or application becomes "online" again.
A couple of suitable services are:
Amazon Cognito Sync is an AWS service and client library that enables cross-device syncing of application-related user data. You can use it to synchronize user profile data across mobile devices and the web without requiring your own backend. The client libraries cache data locally so your app can read and write data regardless of device connectivity status. When the device is online, you can synchronize data, and if you set up push sync, notify other devices immediately that an update is available.
AWS AppSync enables developers to interact with their data by using a managed GraphQL service. GraphQL offers many benefits over traditional gateways, encourages declarative coding style, and works seamlessly with modern tools and frameworks, including React, React Native, iOS, and Android. GraphQL is a data language that was developed to enable apps to fetch data from servers. It has a declarative, self-documenting style. In a GraphQL operation, the client specifies how to structure the data when it is returned by the server. This makes it possible for the client to query only for the data it needs, in the format that it needs it in.

Android offline mode (syncing data when app goes online)

I want to gather data in online/offline mode, and when the internet connection is dropped data should be store in locally, and once the internet connection is back data should sync/push to the server.
What library or technique recommended for achieve that?
Try to store data in offline using Room data base or Sqlite. after storing the data check internet connection continuously, if internet has connected upload that data to your server and drop local data.

Confirming document upload in couchbase

I am creating an app that logs data. I am creating documents that have the data and sending those documents to a couchbase server. Or I am trying to anyways. One major concern I have is how do I confirm a document is stored on the server so that it can be immediately deleted on the device? I am hoping there is a quick and efficient way to do this. The end result is to have a thread constantly checking if there is a connection to couchbase, and if so start sending data up to clear it off the device. Most documentation seems to be regarding syncying the database, however I don't want to do this because I don't want to keep a copy of the data on the device. It would take up too much storage. Thanks for any help.
EDIT: For clarification, I currently have the app storing many data points in documents. I want to send these documents to a couchbase server. I don't want to "sync" the documents, but rather just insert them into the database then immediately delete them off the device. How would one go about doing this? Most examples I have seen typically sync documents such as profile information where changes can be made in various synced databases and all those changes would appear in every database. Instead I want a 1 way relationship with the database were information is sent, confirmed as received, then immediately deleted from the device.
There are at least a few possibilities.
If you are expecting a solid network connection, or are ok with handling errors yourself, you can achieve this with a direct REST call to Sync Gateway. You can, of course, always write your own REST server that talks directly to Couchbase Server, too.
The second way relies on an older version of Couchbase Lite. Couchbase Lite 2.x is a major rewrite of the product. As of the current shipping version (2.1), it does not support this approach, so you'll need to use the 1.x version (1.3 or later, IIRC). See further down for how to approach this with 2.1.
Set up a push only replication. After replication, cycle through the docs and purge all the ones that are not still pending. (This uses the isDocumentPending method on the Replication class. That's the key piece not available as of 2.1.) You can either run one shot replications and do this after the replication completes, or monitor the replication state of a continuous replication.
Purging a document from the local CB Lite database effectively makes it act as if it never existed on that device. By running a push only replication, you don't have to worry about the docs getting sent back to the device.
Using 2.1, you can't as easily determine if a document has been replicated. So you need to run a replication to completion while avoiding a race condition with writing something new.
One approach here is to pause writing documents, run a one shot replication, then purge the documents before starting up again. You could also work out something with alternating databases, or tracking documents yourself somehow, etc.
For completeness, if you were in a situation where you had a mixed use, that is, wanted only some documents pushed up off the device and forgotten, and some synced, you would control this through Sync Gateway channels.
I don't know Lite and Sync Gateway well enough, but from a Server perspective:
You could use the new Eventing service in Couchbase. When a document is created in bucket A, you could write an event to copy that document over to bucket B. Then, if the documents are deleted on the device, it wouldn't matter if they get deleted from bucket A.
I have a bucket "staging" and a bucket "final". I created a function called "moveIt" with "final" (I aliased as 'f').
The OnUpdate function could be as simple as:
function OnUpdate(doc, meta) {
f[meta.id] = doc;
}
My main concern would be the timing. I don't think there's an easy way for your mobile app to know that the event has finished copying a document before you decide to delete it in Lite and start a Sync. But it might be worth a try. Check out the docs to learn more about the Eventing service details.
In Couchbase Lite 2.5, you can use replicated events to detect when a document has synced (pushed to server or pulled from server). You can register a callback on the Couchbase Lite replicator to detect if the documents have been pushed to the sync gateway and then use the purge API to locally purge

Accessing database from Broadcast receiver as well as with the app

I have built a simple application that accepts data entered by the user and saves it to the local sqlite database. If wifi connection is available it will transmit the data to a REST service hosted on a remote server.
I have done the above part and it is working pretty fine. If WIFI is not available it will just move on and will expect new data from the user.
When the wifi becomes available, i have registered a broadcast receiver which will hit my database and get the values stored and send them to the remote server.
I would like to know, while the broadcast receiver is trying to query my database, if the user is entering data at the same time and it is being saved in the same database, will it fire a SQLException.
As i recall, only one service can access the SQL instance at a time. If it will pose a problem what shall i do to overcome it. I have looked at ContentProviders, would that be the solution?
I am fairly new to android. Please advice.
You may want to take a look at this.
What are the best practices for SQLite on Android?
For me, I would suggest to always create a ContentProvider together with DatabaseHelper when you need Database, no matter you need to provide your data to external application or not. It is actually not difficult to do, the best reference I used to build my ContentProvider is DeskClock, the official app from Android.
Edit:
As a side note, you should consider to create a IntentService to be called by your boardcast receiver to do the work, as broadcast receiver should not be used for long running task, like sending things to server.
BroadcastReceiver#onReceive
When it runs on the main thread you should never perform long-running
operations in it (there is a timeout of 10 seconds that the system
allows before considering the receiver to be blocked and a candidate
to be killed).

Offline storage management for android

Theme : Newspaper updates in android application.
How to fetch or retrieve data from server and post updates on android application . How to manage offline storage means whenever there is no internet connection how the data gone be updated on android application , atleast how it consider showing updates on android application . If any one known this issue please answer about it .
I am actually using php or json as intermediate files for fetching data from server and send updates to android application but its seems to be more complex and if i wont get the permission to access the server side files , how do i manage for updates ? whether is it necessary to have permission to access the server files ?
More about the topics : if i want to syncronise the update with website , how do i handle it or implement it ? i am not asking any sort of coding here .
How to fetch or retrieve data from server and post updates on android application
use HTTPClient.
How to manage offline storage means whenever there is no internet connection how the data gone be updated on android application
I think you don't understand what offline storage means. If there is no internet connection, that's it. You are not able to update your content. Offline storage is useful if you have internet connection, but not everytime. The content you downloaded when you had internet connection can be saved to SQLLite to be loaded when you don't have internet connection.
I am actually using php or json as intermediate files for fetching data from server and send updates to android application but its seems to be more complex and if i wont get the permission to access the server side files , how do i manage for updates ? whether is it necessary to have permission to access the server files ?
Create WebService as an interface. Do not let other system to be able to directly access your files. Or just create a PHP files that basically return Json or XML Data.
Other option : create an RSS.
More about the topics : if i want to syncronise the update with website , how do i handle it or implement it ? i am not asking any sort of coding here .
Create an event to start sync using HTTPClient. If there is new update, save it to SQLLite(for offline storage) and display the content. The event can be triggered during the start of your application or clicking refresh button and if Internet exist.
Update :
There is a new framework called couchbase mobile. You can sync the local mobile db from a couch server. You can insert/update the data locally(offline mode) and then the data can be synced also to the couch server, whenever you have internet connection. This means the need to create HTTPClient is no longer necessary.
For the database, try cloudant.

Categories