MongoDB.live, free & fully virtual. Register Now MongoDB.live, free & fully virtual. Register Now

Can't Read or Listen Changes when connection dropped

as the title say…

all working fine with internet connection, but when connection dropped,
my local data are not accessible

but, for create, when i create a new register, its not update or callback for my ui, and when the connection back, it updates right
its like a draftState, waiting for connection

look this video:
0:00 to 0:17 connection on
0:18 to 0:38 connection off
0:39 to end connection on

@Royal_Advice I’m not sure what your code looks like, but we have a RN example which works when it goes offline - see here:

This only works when you open your app with internet on and later drop the internet connection with your app open. But, it does not work when you open your app with internet off.

@Promit_Rai The first time you launch the app, you must have internet, otherwise you cannot login and get a valid user. Subsequent app starts can then be made offline.

Yeah that is what I mean. For the very first time when I open my app, I open with internet connection , login the user and sync with my cluster. It reads all the data from my cluster. And then I close my app with still user logged in. Then turn off my wifi and open my app. This time it does not return anything.

@Promit_Rai As mentioned in this post -

You should be able to use the new Realm(getConfig(app.currentUser)); API when you are offline to open the cached realm on disk. If this is not happening then please step through it with a debugger and see where your logic is not hitting this API.

my code looks like this:

export function getRealmApp() { const appId = 'app-name'; // Set Realm app ID here. const appConfig = { id: appId, timeout: 10000, }; return new Realm.App(appConfig); }

async function anonymousLogin() {
let user;
try {
const app = getRealmApp(); // pass in the appConfig variable that you created earlier
if (!app.currentUser) {
const credentials = Realm.Credentials.anonymous(); // create an anonymous credential
user = await app.logIn(credentials);
return user;
} else {
return app.currentUser
}
} catch (error) {
console.log(error)
throw Error logging in anonymously: ${JSON.stringify(error, null, 2)};
}
}

export async function openRealmSync() {
	let user = await anonymousLogin();
	let realm;
	try {
		const config = {
			schema: [Task.schema],
			sync: {
				user: user,
				partitionValue: "GLOBAL",
			},
			path: "myrealmSync"
		};

		realm = await Realm.open(config);
		return realm
	} catch (error) {
		console.log(error)
		throw `Error opening realm: ${JSON.stringify(error, null, 2)}`;
	}
}
export async function readSyncTasks() {
	return openRealmSync()
		.then(realm => {
			const Tasks = realm.objects("Task")
			return Tasks
		})
		.catch(err => {
			console.log(err)
		})
}

export async function createSyncTask() {
	openRealmSync()
		.then(realm => {
			realm.write(() => {
				realm.create("Task", {
					_id: ObjectID(),
					_partition: "GLOBAL",
					name: "go grocery shopping",
					status: "Open",
				});
			});
		})
		.catch(err => {
			console.log(err)
		})
}

ok, i found my error, i wasn`t using cached user, my logic was not working well

Thanks ! I will have a look again and try to figure out.

I think you are missing new Realm(config) . But in my case, even if I use, its not working at the moment.

my errors was here
return await Realm.open(getConfig(user));

and must be like this for cached user
return new Realm(getConfig(app.currentUser));

This is my code. Am I missing anything ?

getRealmApp.js

import Realm from 'realm';

let app;
    export function getRealmApp() {
      if (app === undefined) {
        const appId = 'APP_ID';

        const appConfig = {
          id: appId,
          timeout: 10000,
          app: {
            name: 'default',
            version: '0',
          },
        };
        app = new Realm.App(appConfig);
      }
      return app;
    }

AuthProvider.js

import React, {useContext, useState, useEffect} from 'react';
import Realm from 'realm';
import {getRealmApp} from '../config/getRealmApp';

const app = getRealmApp();
const AuthContext = React.createContext(null);

const AuthProvider = ({children}) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    const {currentUser} = app;
    setUser(currentUser);
  }, []);

  const logIn = async (email, password) => {
    try {
      const creds = Realm.Credentials.emailPassword(email, password);
      const newUser = await app.logIn(creds);
      setUser(newUser);
      console.log(`Logged in as ${newUser.id}, ${newUser.state}`);
    } catch (e) {
      console.log('ERROR', e);
    }
  };
  return (
    <AuthContext.Provider
      value={{
        logIn,
        user,
      }}>
      {children}
    </AuthContext.Provider>
  );
};

const useAuth = () => {
  const auth = useContext(AuthContext);
  if (auth == null) {
    throw new Error('useAuth() called outside of a AuthProvider?');
  }
  return auth;
};

export {AuthProvider, useAuth};

DataProvider.js

            import React, {useContext, useState, useEffect, useRef} from 'react';
            import Realm from 'realm';
            import {useAuth} from './AuthProvider';
            const DataContext = React.createContext(null);

            const DataProvider = ({children, projectId}) => {
              const {user} = useAuth();

              const [sessions, setSessions] = useState([]);

             useEffect(() => {
                if (user == null) {
                  console.warn('Schema must be authenticated!');
                  return;
                }
            const config = {
                  schema: [sessionSchema],
             sync: {
                    user,
                    partitionValue: 'PARTITION VALUE',
                  },
            };
                // for offline
                 const localRealm = new Realm(config);
                 const syncSessions = localRealm.objects('session');
             setSessions([...syncSessions]);

// for online  , I have comment it out 
   // Realm.open(config)
   // .then((openedRealm) => {
   // if (canceled) {
   // openedRealm.close();
  // return;
  // }
  //  realmRef.current = openedRealm;
  //   const syncSessions = openedRealm.objects('session');
  //  openedRealm.addListener('change', () => {
  //   setSessions([...syncSessions]);
// });
//  setSessions([...syncSessions]);
 // return () => {
    //   const realm = realmRef.current;
    //   if (realm != null) {
    //     realm.removeAllListeners();
    //     realm.close();
    //     realmRef.current = null;
    //   }
    // };
            }, [user]);
        return (
            <DataContext.Provider
              value={{
                sessions,
              }}>
              {children}
            </DataContext.Provider>
          );
            }
        const useDatas = () => {
          const value = useContext(DataContext);
          if (value == null) {
            throw new Error('useDatas() called outside of a TasksProvider?');
          }
          return value;
        };

        export {DataProvider, useDatas};

with this code, you can connect and open a realm, this is not especifically for offline, because you need to treat your connection and know if is reachable. but it will work for you to understand better
obs: try not to use partition values with space

    async function getRealm() {
        const app = new Realm.App("your-app-id");
        if (app.currentUser) {
            // A user had already logged in - open the Realm synchronously
            return new Realm(getConfig(app.currentUser));
        }

        // We don't have a user - login a user and open the realm async
          const creds = Realm.Credentials.emailPassword(email, password);
        const user = await app.logIn(creds);
        return await Realm.open(getConfig(user));
    }

    function getConfig(user) {
        return {
            schema: [sessionSchema],
            sync: {
                user,
                partitionValue: "my-partition"
            }
        };
    }

then you can use like this:

const sessions = getRealm().objects("sessionSchema");
console.log(sessions);