Flexible sync when device is offline

Hello, Please how can I use Flexible sync in realm with React Native when the device is offline? When I am online, everything works well, but when I go offline, the RealmProvider gets stuck at the fallback without being able to pass through. Here is my code below.

<UserProvider fallback={<FallBackNavigator />}>
      <RealmProvider
        sync={{
          flexible: true,
          initialSubscriptions: {
            update: (subs, realm) => {
                subs.add(realm.objects('courses'),{
                  name: 'allCoursesSubscription',
              })
            },
            rerunOnOpen: true,
          },
        }}
        fallback={() => <ActivityIndicator size={'large'} style={{ position: 'absolute', zIndex: 999, top: DEVICE_HEIGHT * 0.5, left: DEVICE_WIDTH * 0.46 }} />}
      >
        <Navigator
          initialRouteName="Splash"
          screenOptions={{
            headerShown: false,
          }}
        >
          <Screen name="Splash" component={Splash} />
          <Screen name="Onboarding" component={Onboarding} />
          <Screen name="DrawerNavigator" component={DrawerNavigator} />
          <Screen name="BottomNavigator" component={BottomNavigator} />
        </Navigator>
      </RealmProvider>
    </UserProvider>

I have checked other topics on this with no way to get unblocked, I have also read the docs all through.
I only have a problem with it when I am offline. Please help

I finally found out how to solve the Issue I was having. I was forgetting the user field in the sync property of the RealmProvider. So I added it and everything was now okay

1 Like

Hey @Oben_Tabiayuk can you expand how you solved it. @Andrew_Meyer can you advise.
Same with me, when I am online, everything works well, but when I go offline and reopen the app the RealmProvider gets stuck at the fallback without being able to sync data.

<RealmProvider
  sync={{
    flexible: true,
    onError: (_, error) => {
      console.log(error);
    },
  }}
  fallback={LoadingIndicator}>
  <App />
</RealmProvider>

I want to tell Realm to only connect to the remote server if the device is online. If the device is offline, Realm should immediately return the local subscription.

@Siso_Ngqolosi We are planning to update this in v13, but the default behaviors for opening Realm are unfortunately not very offline first friendly. However this can be solved with the following settings:

<RealmProvider
  sync={{
    flexible: true,
    existingRealmBehavior: {
        openBehavior: "openImmediately",
    },
    newRealmFileBehavior: {
        openBehavior: "downloadBeforeOpen",
    },
    onError: (_, error) => {
      console.log(error);
    },
  }}
  fallback={LoadingIndicator}>
  <App />
</RealmProvider>

Let us know if this helps!

Thanks @Andrew_Meyer for that.

Also found this and it seems to be working . Just have to fix the error message is telling me that the type "downloadBeforeOpen" is not assignable to the type Realm.OpenRealmBehaviorType .

const realmAccessBehavior: Realm.OpenRealmBehaviorConfiguration = {
    type: 'downloadBeforeOpen',
    timeOutBehavior: 'openLocalRealm',
    timeOut: 1000,
  };

  return (
   ...
          <RealmProvider
            sync={{
              flexible: true,
              newRealmFileBehavior: realmAccessBehavior,
              existingRealmFileBehavior: realmAccessBehavior,
              onError: (_, error) => {
                console.log(error);
              },
            }}
            fallback={LoadingIndicator}>
...

Unrelated: Enjoyed your talk realm talk here: https://youtu.be/biIPsXoHu7Q?si=WysWpd7PkZbbr7e0

1 Like

@Siso_Ngqolosi use this to solve your error

const existingRealmFileBehaviorConfig: OpenRealmBehaviorConfiguration = {
    type: OpenRealmBehaviorType.OpenImmediately,
  };

  const newRealmFileBehaviorConfig: OpenRealmBehaviorConfiguration = {
    type: OpenRealmBehaviorType.OpenImmediately,
  };

 <RealmProvider
      sync={{
        user: app.currentUser!,
        flexible: true,
        newRealmFileBehavior: newRealmFileBehaviorConfig,
        existingRealmFileBehavior: existingRealmFileBehaviorConfig,
1 Like

Hey @Andrew_Meyer, an idea why this might be happening?

Issue Description

This problem occurs when modifications are made to the local realm database while the application is running in an offline mode (no internet connection). When the application is subsequently brought back online, the changes made to the local database are overwritten by the data stored in MongoDB.

Reproduction Steps

To replicate this issue, follow these steps:

  1. Launch the application and log in. Select your event and proceed to check in a guest.
  2. Disable your phone’s network connection to simulate an offline state.
  3. Close the application (referred to as “the app”).
  4. Reopen the application while still in offline mode.
  5. Perform a guest check-in.
  6. Re-establish your phone’s network connection, bringing the application back online.
  7. Once the application is synchronized with the server, you will observe that the guest’s ticket status has reverted to “not checked in.”
const realmAccessBehavior = {
    type: 'downloadBeforeOpen',
    timeOutBehavior: 'openLocalRealm',
    timeOut: 1000,
  };

  return (
   ...
          <RealmProvider
            sync={{
              flexible: true,
              newRealmFileBehavior: realmAccessBehavior,
              existingRealmFileBehavior: realmAccessBehavior,
              onError: (_, error) => {
                console.log(error);
              },
            }}
            fallback={LoadingIndicator}>
...

@Siso_Ngqolosi Sorry for the late reply, this seems to have fallen through my filter.

This should be working. Can you check the logs in Atlas if there was an error? Perhaps the permissions on this schema are too restrictive. If on the server side, the user didn’t have the rights to modify this object, then they would be reverted on sync.

1 Like

Is this due to it being guest?

Perform a guest check-in

Because the anon auth page has this very big warning:

An Anonymous user object is not intended to persist data. Once a user logs out, the user cannot retrieve any previous user data.

So “once user logs out” seems to be maybe happening in the transition to being a guest user offline then having a connection established?

@Andrew_Meyer I would really appreciate your help on this – I’m stuck after several days of trying to debug.

I’ve followed the instructions from Access a synced Realm while offline, but my app is still stalling (getting stuck on the fallback view) when I open it without an internet connection. Auth and Sync work as expected when online.

When testing this I wipe app data, launch with network connection and sign in, close the app and attempt to reopen offline.

A few things about my code below:

  • I’ve tried this with AND without the initialSubscriptions option
  • I have two Schemas. SurveyResults is set up for Asymmetric Sync while SurveyDesigns is set up for two-way flexible sync. Both of these work successfully online.
  • The onError block of the sync configuration contains a console.log message that never fires.
"expo": "~48.0.21",
"react": "18.2.0",
"realm": "^12.11.1",
"@realm/react": "^0.8.0",
const RealmWrapper = ({children}) => {

    const [syncError, setSyncError] = useState(null);
    const realmAccessBehavior = {
        type: OpenRealmBehaviorType.OpenImmediately,
    };



    return (
        <AppProvider id={APP_ID} logLevel={'trace'} logger={(level, message) => console.log(`[${level}]: ${message}`)}>
            <UserProvider fallback={LoginWrapper}>
                <RealmProvider
                    schema={[SurveyResults, SurveyDesign]}
                    fallback={<RealmLoading />}
                    sync={{
                        flexible: true,
                        existingRealmBehavior: realmAccessBehavior,
                        newRealmFileBehavior: realmAccessBehavior,
                        onError: (_, error) => {
                            console.log("I'm In the sync error handler!");
                            setSyncError(error);
                            
                        },
                        // initialSubscriptions: {
                        //     update(subs, realm) {
                        //     subs.add(realm.objects(SurveyDesign).filtered("name != nil"), {
                        //         name: "All Survey Designs",
                        //         behavior: WaitForSync.Never,
                        //     });
                        //     },
                        // },
                    }}
                >
                    {children}
                </RealmProvider>
            </UserProvider>
        </AppProvider>

    );
}

I’m able to see the following errors (specific urls and tokens removed) in the console when launching the app offline:

 ERROR  [Realm.Sync.Client.Network - error] Failed to resolve 'ws.services.cloud.mongodb.com:443': Host not found (authoritative)

 ERROR  [Realm.App - error] App: request location failed (CustomError -1): request to https://...../location failed, reason: Network request failed

 ERROR  [Realm.App - error] App: refresh_access_token: ...... -> 0 ERROR: request to https://....../location failed, reason: Network request failed

Any help would really be a lifesaver, thanks!

@Austin_Carnahan Just to ensure it’s not a problem with versioning, can you ensure that the realm and @realm/react dependencies are at the latest release? There were some issues fixed in core-realm with request location failed that might be at the root of this issue.

I’m having the same problem on the newest version, realm@12.12.1 and @realm/react@0.9.0

I’ve upgraded my project to the following, but no changes in resulting behavior:

"realm": "12.12.1",
"@realm/react": "0.9.0",
"expo": "^51.0.24",
"react": "18.2.0",
"react-native": "0.74.3",

I have two object schemas referenced in my previous post:

SurveyDesigns: configured for 2-way sync with a subscription
SurveyResults: configured for asymmetric sync

I was curious if maybe these two configurations were incompatible within the same realm. So I removed SurveyResults and ran again with schema={[SurveyDesign]} with no change in behavior.

@Patryk_Rosiak Can you provide your configuration and information about your schema and subscriptions?