Re-Login to App while still offline? Could sync_metadata.realm be utilized?

One of the limitations of offline-first apps is that, if a user logs out before going offline, he/she cannot get back in while offline (having no internet access) as authentication happens on the server.

When looking through the files Realm Sync uses on the device I noticed a database called sync_metadata.realm, which seems to contain authentication details:

...
exports.UserMetadata = {
  name: 'UserMetadata',
  properties: {
    identity: 'string',
    local_uuid: 'string',
    marked_for_removal: 'bool',
    refresh_token: 'string?',
    provider_type: 'string',
    access_token: 'string?',
    identities: 'UserIdentity[]',
    profile: 'profile',
    state: 'int',
    device_id: 'string'
  }
}

exports.current_user_identity = {
  name: 'current_user_identity',
  properties: {
    current_user_identity: 'string'
  }
}
...

Within UserMetadata there is a refresh_token and access_token available after a user logs in and these are cleared when a user logs out. The user identity of each previously logged in user is also saved in this db file.

This gave me the idea that this data could possibly be used to re-login previously authenticated users while they are offline. Is there an API available which officially supports this? (Based on previous discussions here, I assume there is not, but if there already is please point me to the API and the rest of my post would be moot).

(getting a 403 error repeatedly when trying to post the second part of this… :thinking:)

1 Like

If there is no official API which supports re-login in an offline situation, I thought that maybe I could access and cache the refresh_token and access_token in on-device storage while the user is online and use it to re-login while the user is offline. I know this might have security implications, but this is not a concern for the current app.

As a proof of concept, I tested the following using iOS Simulator with the offline-enabled demo Task Tracker React Native app:

(still getting a 403 error every when trying to post the remaining part of this… :thinking:)

(continued… due to 403 errors)

  • Login to the Task Tracker React Native app and create some Tasks
  • Access the metadata file: cd $HOME/Library/Developer/CoreSimulator/Devices/8B6.../data/Containers/Data/Application/2CC.../Documents/mongodb-realm/tasktracker-q.../server-utility/metadata
  • Backup the file: cp -v sync_metadata.realm sync_metadata.loggedin.realm
  • Logout while still online (which clears the auth data from sync_metadata.realm)
  • Exit the app completely
  • Backup the logged out file (just in case): mv -v sync_metadata.realm sync_metadata.loggedout.realm
  • Go offline (deactivate Wifi/Ethernet on macOS)
  • Replace the file with the logged in version: mv -v sync_metadata.loggedin.realm sync_metadata.realm
  • Start the app while still offline: I am logged in as the previous logged in user.
  • Go back online (re-activate Wifi/Ethernet on macOS)
  • Check that there are no errors from connecting back to the MongoDB Realm Sync backend. Everything works.

The path for the Realm files can be found for example by using: console.log('* REALM PATH: ' + Realm.defaultPath); somewhere after Realm.open(config). And the Realm files can be opened on the desktop using MongoDB Realm Studio.

This seems to work in principle, but obviously copying and swapping the sync_metadata.realm file would not be feasible to do from within the app. Yet possibly re-inserting the refresh_token and access_token could be done programmatically while the user is logged out and offline.

I am only interested to re-login the most recently logged out user. Would this be feasible and how could I go about doing that in javascript on React Native? What side effects or problems could this cause?

1 Like

Offline Re-Login of an offline-first app should actually be built into the Realm framework. Apps like 1Password and some others allow re-login on the same device while offline. As shown above, Realm actually has a database - sync_metadata.realm - which has the potential to cache credentials.

I will request offline re-login capability as a feature request , as soon as I have confirmation, that there is no API to do that with the current version.

An answer about this and with regard to the other questions would really be helpful.

1 Like

Thought I was alone on this, this really nags me for a weeks not, I’m surprised to see no answer from the Mongodb Realm Team.

I’m using in React-Native with a @realm/react package

if you ever find a solution please let me know. :slight_smile:

Cheers from Tanzania

I know this is an old thread, but just for the record, Realm caches de user when you log in for the first time.

Sou, you can do something like this (React Native version):

const app = new Realm.App(appConfig);

const credentials = Realm.Credentials.jwt(accessToken);

try {
  // Try to login, but ignore the error to allow continue offline.
  await app.logIn(credentials);
} catch (err) {
  console.warn(err);
}

if (app.currentUser) {
  // Ensure that exists a cached or logged user
  throw new Error('Realm login failed: current user not found');
}

const realm = await Realm.open({
      schema: config.schema,
      schemaVersion: config.schemaVersion,
      sync: {
        user: app.currentUser,
        partitionValue: config.partition,
        ...
      },
    });

// Done!!

Docs: https://www.mongodb.com/docs/realm/sdk/node/examples/open-and-close-a-realm/#open-a-synced-realm-while-offline

1 Like