Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use in combination with Expo router v3 #21

Open
ma10as opened this issue Mar 25, 2024 · 5 comments
Open

Use in combination with Expo router v3 #21

ma10as opened this issue Mar 25, 2024 · 5 comments

Comments

@ma10as
Copy link

ma10as commented Mar 25, 2024

Describe the bug
I have used the Auth logic from this repo for some time now without problems.
Now i try to switch from React Navigation to Expo router v3 (file-based routing), and i ran into a issue.

On first load of the app the app doesn't run the handleOnLogin() function from useAuth. The app is never leaving the isLoading state before being reloaded.

I'm trying to follow this instruction https://docs.expo.dev/router/reference/authentication/#example-authentication-context

app/_layout.jsx

import { Slot } from 'expo-router';
import Constants from 'expo-constants';
import Meteor from '@meteorrn/core';
import AsyncStorage from '@react-native-async-storage/async-storage';

import { AuthContext } from '@/auth/AuthContext';
import { useAuth } from '@/auth/useAuth';

Meteor.connect(Constants.expoConfig?.extra?.meteorUrl, { AsyncStorage });

const Root = () => {
  const { authContext } = useAuth();

  return (
    <AuthContext.Provider value={authContext}>
      <Slot />
    </AuthContext.Provider>
  );
};

export default Root;

app/(app)/_layout.jsx

import { Text } from 'react-native';
import React from 'react';
import { useAuth } from '@/auth/useAuth';
import { Redirect, Stack } from 'expo-router';

const AppLayout = () => {
  const { state } = useAuth();
  const { userToken, isLoading } = state;

  if (isLoading) {
    return <Text>Loading...</Text>;
  }

  if (!userToken) {
    // On web, static rendering will stop here as the user is not authenticated
    // in the headless Node process that the pages are rendered in.
    return <Redirect href="/sign-in" />;
  }

  return <Stack />;
};

export default AppLayout;

useAuth.jsx

import { Alert } from 'react-native';
import Meteor from '@meteorrn/core';
import { router } from 'expo-router';

const initialState = {
  isLoading: true,
  isSignout: false,
  userToken: null,
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'RESTORE_TOKEN':
      return {
        ...state,
        userToken: action.token,
        isLoading: false,
      };
    case 'SIGN_IN':
      return {
        ...state,
        isSignout: false,
        userToken: action.token,
      };
    case 'SIGN_OUT':
      return {
        ...state,
        isSignout: true,
        userToken: null,
      };
  }
};

const Data = Meteor.getData();

export const useAuth = () => {
  const [state, dispatch] = useReducer(reducer, initialState, undefined);

  useEffect(() => {
    console.log('useEffect');
    const handleOnLogin = () =>  dispatch({ type: 'RESTORE_TOKEN', token: Meteor.getAuthToken() });

    Data.on('onLogin', handleOnLogin);
    return () => Data.off('onLogin', handleOnLogin);
  }, []);

  const authContext = useMemo(
    () => ({
      signIn: ({ input, onError }) => {
        Meteor.loginWithPassword(input.email, input.password, async (err) => {
          if (err) {
            Alert.alert('Error', err.reason);
          }
          console.log('signIn - Compleate');
          const token = Meteor.getAuthToken();
          const type = 'SIGN_IN';
          dispatch({ type, token });
          router.replace('/');
        });
      },
      signOut: () => {
        Meteor.logout((err) => {
          if (err) {
            Alert.alert('Error', err);
          }
          dispatch({ type: 'SIGN_OUT' });
        });
      },
    }),
    []
  );
  return { state, authContext };
};

What could the problem be?

@jankapunkt
Copy link
Owner

Hi @ma10as thanks for reporting. Can you run Meteor.enableVerbose() and see what the console.info prints regarding the token? The onLogin will only run of the current token is found. I just want to make sure this is not an issue with the library. Also - which version of @meteorrn/core is currently installed at your project?

@ma10as
Copy link
Author

ma10as commented Mar 26, 2024

Hi @jankapunkt
I ran the Meteor.enableVerbose() function and the result is INFO Connected to DDP server.
I use @meteorrn/core : "2.7.1"

@jankapunkt
Copy link
Owner

@ma10as I fixed a few things in the library and released 2.8.0, can you try this one first, please? Apart from that I will try to reproduce and see if the issue is actually related with the expo file router.

@ma10as
Copy link
Author

ma10as commented Mar 26, 2024

@jankapunkt I will try to update to 2.8.0 and i will come back later today👍🏻

@ma10as
Copy link
Author

ma10as commented Mar 26, 2024

Hi @jankapunkt i now updatet to 2.8.0
Now I am stuck on the loading page and it is not leaving it after reload.
The Meteor.enableVerbose() now returns 3 results
INFO Connected to DDP server.,
INFO User._loginWithToken::: token: ERtGkUfUhmiZBZ4GBfiPD_3F-FYspj5V4a_fT3yr4wG and
INFO User._handleLoginCallback::: token: ERtGkUfUhmiZBZ4GBfiPD_3F-FYspj5V4a_fT3yr4wG id: Z8HiZDuqkzujLTzQT.

And it looks like the useReducer functions runs with the type RESTORE_TOKEN but the token: null

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants