Expo-router authentication with Realmdb

So I have been trying out Realmdb recently after hearing a lot of good news about it and I am impressed with how easy it is to set up.

Currently, i am using Expo-router for navigation in my project, but then i noticed issues if i can call it that.
So the way the UserProvider works is that it takes in children props and a fallback component, The children props could be the entire navigation container of your application if you are using ReactNavigation, and then the fallback could be a Stack navigation, so that navigation u are passing as a fallback can have multiple screens, maybe, a login, registration screen.

Since the expo-router does not work that (Because it is a file-based routing) way I can only add a single component as a fallback and not a navigation stack. Inside the _layout.tsx file, i added the UserProvider there and passed in the component from expo-router which should render out everything. I want to know if there is a way i can have a fallback with multiple screens, i tried something like rendering the UserProvider conditionally if a user is authenticated or not, but that does not work as well.

1 Like

Hello.
I have also come across that. Right now the way I handle it, is to put the Stack or Slot in the fallback. And then I handle the shown routes logic based on auth status manually within the app routes. I have two folders and (intro) folder and a (main) folder. If the user is authenticated I redirect from the (intro) folder to the main folder. This allows me to have more screens in unauthenticated flow.

Hey Stef,

Do you have an example of how you approached that?

I have tried replacing fallback component with Stack or Slot but after auth,

Render Error
No user found. Did you forget to wrap your component in <UserProvider> despite auth being successful.

In my custom providers

const Providers = (props: React.PropsWithChildren): React.JSX.Element => {
  return (
    <SessionProvider>
      <AppProvider id={SYNC_CONFIG.appId}>
        <UserProvider fallback={<Stack />}>{props.children}</UserProvider>
      </AppProvider>
    </SessionProvider>
  );
};

export default Providers;

In my app/_layout.tsx

export default function RootLayout(): React.JSX.Element {
  return (
    <Providers>
      <Stack />
    </Providers>
  );
}

In my app/index.tsx

export default function Root(): React.JSX.Element {
  const { session, isLoading } = useSession();

  if (isLoading) {
    return <LoadingScreen />;
  }

  const redirectPath = session ? '/(app)/home' : '/(auth)/sign-in';

  return <Redirect href={redirectPath} />;
}

Only in home did I use useUser. And from console.logs, it seems that the authentication is successful. But when it tries to redirect, the above error is always thrown.

<View style={{ flex: 1, paddingTop: insets.top }}>
      <RealmProvider schema={schemas} schemaVersion={1}>
        <AppProvider id={SYNC_CONFIG.appId}>
          <UserProvider
            fallback={
              <Stack screenOptions={{ headerTitle: "When no user found" }}>
                <Stack.Screen name="index" />
              </Stack>
            }
          >
            <Stack screenOptions={{ headerTitle: "When user available" }}>
              <Stack.Screen name="(protected)/home" />
            </Stack>
          </UserProvider>
        </AppProvider>
      </RealmProvider>
    </View>

I tried it. However, the Stack Navigator does not work with the UserProvider. How did you manage the auth state? Can you share some code example?

For anyone who is facing this issue, I managed to resolve this.

My _layout.tsx is available here