realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.72k stars 564 forks source link

realmRef on RealmProvider doesn't allow syncSession.addProgressNotification #5144

Open LukeStorry opened 1 year ago

LukeStorry commented 1 year ago

How frequently does the bug occur?

All the time

Description

We're having issues getting anything out of realmRef.current

Previously using const realm = useRealm(); realm.syncSession.addProgressNotification(...) within the Realm Provider worked well.

Now we'd like to use the values from this progress notification to display within the fallback component to display a loading update to users for longer syncs.

However, when trying to use the realmRef as described in #4571, the value provided is either empty, or doesn't trigger a useEffect when needed.

Stacktrace & log output

No response

Can you reproduce the bug?

Yes, always

Reproduction Steps

Here is a reduced reproduction:

export function RealmAppProvider({children}: {children: React.ReactNode}) {
  const [syncProgress, setSyncProgress] = React.useState(0);
  const realmRef = React.useRef<Realm | null>(null);
  const appRef = React.useRef<Realm.App | null>(null);

  React.useEffect(() => {
    const realm = realmRef.current;
    console.log({realm});
    if (realm) {
      console.log('we have realm!');
      const syncSession = realm.syncSession;
      if (syncSession) {
        console.log('we have syncSession!');
        syncSession.addProgressNotification(
          Realm.ProgressDirection.Download,
          Realm.ProgressMode.ReportIndefinitely,
          (transferred, transferable) => {
            console.log({transferred, transferable});
            if (transferable > 0) {
              setSyncProgress(transferred / transferable);
            }
          },
        );
      }
    }
  }, [realmRef.current?.syncSession?.state, setSyncProgress]);

  React.useEffect(() => {
    console.log('SyncProgress: ', syncProgress);
  }, [syncProgress]);

  return (
    <AppProvider id={REALM_APP_ID} appRef={appRef}>
      <LdtAuthProvider>
        <UserProvider fallback={<AuthNavigator />}>
          <RealmProvider
            realmRef={realmRef}
            sync={{
              flexible: true,
              initialSubscriptions: {
                update: (subs, realm) => {
                  const users = realm.objects('User');
                  subs.add(users, {name: 'User'});
                },
                rerunOnOpen: true,
              },
            }}
            fallback={<Text>{syncProgress} </Text>}>
            {children}
          </RealmProvider>
        </UserProvider>
      </LdtAuthProvider>
    </AppProvider>
  );
}

On app load, sync occurs, but the only console output is:

{"realm": null}
SyncProgress:  0 

Version

0.4.1

What SDK flavour are you using?

Atlas Device Sync

Are you using encryption?

Yes, using encryption

Platform OS and version(s)

MacOs 13.0

Build environment

No response

Cocoapods version

No response

kneth commented 1 year ago

Progress notification for flexible sync is not working as intended, and we are working (both server and client side) to provide a solution.

I will leave the issue open until we have released it.

carbopilot commented 1 month ago

Any update? :)

gagik commented 1 month ago

@carbopilot The upcoming realm update will fix the progress notification functionality for flexible sync, so we are also now looking into improving the experience of using progress notifications with @realm/react. See https://github.com/realm/realm-js/issues/5459 and https://github.com/realm/realm-js/issues/6797

carbopilot commented 1 month ago

Brilliant. Looking forward to it.