How can I implement offline and online sync?

I want my app to store data when it’s offline and when it’s on it transfers to the atlas.

What I’m doing is I configure a local realm with RealmConfiguration.Builder() and with the help of a timer I create a syncConfiguration flexible with configuration from my atlas and copy from the local Realm to the sync Realm. is this the most correct way?

 Realm previousLocalDB = Realm.getDefaultInstance();
      
      
      
      SyncConfiguration syncConfig = new SyncConfiguration.Builder(userRealm)
                                        .modules(new ModuloUserAndAnalysis1())
                                        .initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
                                            @Override
                                            public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
                                                // add a subscription with a name
                                                
                                                subscriptions.addOrUpdate(Subscription.create("AnalysisSubscription",
                                                        realm.where(AnalysisModel.class).equalTo("partitionId", partitionId)
                                                                .and().equalTo("clientId", clientId)
                                                        .and().equalTo("elementId", elementId)
                                                        .and().isNull("sendDate")
                                                ));

                                                }
                                        })
                                        .allowWritesOnUiThread(true)
                                        .allowQueriesOnUiThread(true)
                                        .build();
                                        
        Realm realmRemoto = Realm.getInstance(syncConfig);
      
        RealmResults<AnalysisModel> previousAnalysis = previousLocalDB.where(AnalysisModel.class).findAll();
        realmRemoto.executeTransaction((realmInTransaction) -> {
            realmInTransaction.copyToRealmOrUpdate(previousAnalysis);
        });
      
      
        realmRemoto.close();
        previousLocalDB.close();

The synced Realm will still work while offline, so you don’t need to create two Realms. Just use the synced Realm the way you would normally, even if offline, and all persisted changes will get synchronized when the device comes back online

1 Like

Thanks for the feedback.

When I tried to use a realm sync by default it always crashed. the operation of is app always starts offline and writes the data.
Code I used.

 protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        Realm.init(this);

       Credentials credentials = Credentials.anonymous();
       User userRealm = app.login(credentials);


        SyncConfiguration syncConfig = new SyncConfiguration.Builder(userRealm)
                .modules(new ModuloUserAndAnalysis1())
                .initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
                    @Override
                    public void configure(Realm realm, MutableSubscriptionSet subscriptions) {                    
                        subscriptions.addOrUpdate(Subscription.create("AnalysisSubscription",
                                realm.where(AnalysisModel.class).equalTo("partitionId", partitionId)
                                        .and().equalTo("clientId", clientId)
                                        .and().equalTo("elementId", elementId)
                                        .and().isNull("sendDate")
                        ));    
                    }
                })
                .allowQueriesOnUiThread(true)
                .allowWritesOnUiThread(true)
                .build();


        Realm.setDefaultConfiguration(syncConfig);

Do you have an example of the error you are seeing when the app crashes? Also, it would help if you could share your schema if possible.

1 Like

Thanks for the feedback.

My question is: when I run offline

User userRealm = app.login(credentials);

the app crashes.

that’s why I create Realm previousLocalDB = Realm.getDefaultInstance();
for when I start offline.

My schema

{
  "title": "AnalysisModel",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "analysisDate": {
      "bsonType": "string"
    },
    "idImage": {
      "bsonType": "string"
    },
    "cpf": {
      "bsonType": "string"
    },
    "clientId": {
      "bsonType": "string"
    },
    "deviceId": {
      "bsonType": "string"
    },
    "elementId": {
      "bsonType": "string"
    },
    "error": {
      "bsonType": "string"
    },
    "partitionId": {
      "bsonType": "string"
    },
    "latitude": {
      "bsonType": "double"
    },
    "longitude": {
      "bsonType": "double"
    },
    "altitude": {
      "bsonType": "double"
    },
    "speed": {
      "bsonType": "double"
    },
    "sendDate": {
      "bsonType": "string"
    }
  }
}

I would like to know how to create a SyncConfiguration offline, because when I run a User with app.currentUser(); does not work

You have to be online to log in and create the user object. After that, the user is cached and you can use the realm offline

2 Likes

this has not helped he is trying to indicate that it is impossible to run sync configuration in the app class since it needs the user to login in

Hi @BIASHARA_KIT,

Let’s put the things in perspective, so that the answer is clear:

  • If you want to open a synched realm, you need to Sync with something: that would be the backend
  • If you need to send/receive data to/from the backend, it requires you to login at least once with a valid user
  • As you’re using Flexible Sync, you also need to tell the backend about the data you’re willing to sync with: again, you need to be online and logged in for that.
  • After that, until you explicitly logout, in all subsequent launches you can just use app.currentUser to work offline.
  • As subscriptions are saved within the local DB, you don’t need to specify them again: if you do, they’ll be refreshed if you’re online, obviously.