I made an app in react native with react-navigation
I defined the navigation like this:
const MainNavigation = (props) => {
const [token, setToken] = useState(null);
useEffect(() => {
(async () => {
const token = await AsyncStorage.getItem("token");
console.log(token);
setToken(token);
})();
}, []);
let screens = (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
</Stack.Navigator>
);
if (token !== null) {
screens = (
<Stack.Navigator>
<Stack.Screen name="Welcome" component={Welcome} />
<Stack.Screen name="Map" component={Map} />
<Stack.Screen name="HomeUser" component={HomeUser} />
<Stack.Screen name="Add" component={Add} />
<Stack.Screen name="Add2" component={Add2} />
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
);
}
return (
<NavigationContainer>
{screens}
</NavigationContainer>
);
};
in logout component I defined this function for clearing localStorage:
pressFn: async () => {
await AsyncStorage.clear();
props.navigation.navigate("Home");
},
How I go to home component?
I apreciate any help
Related
I'm querying if the user has logged in before. I want to have them go to different pages based on the result. onChangeState not working
import { firebase } from './config';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
function App() {
const [initializing, setInitializin] = useState(true);
const [user, setUser] = useState('');
function onAuthStateChanged(user) {
setUser(user);
if (initializing) setInitializin(false);
}
useEffect(() => {
const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged);
return subscriber;
}, []);
if (initializing) return null;
if (!user) {
return (
<NavigationContainer independent={true}>
<Stack.Navigator>
<Stack.Screen
name='Login'
component={LoginScreen}
options={{ headerShown: false, headerBackVisible: false }}
/>
<Stack.Screen
name='Create'
component={CreateAccount}
options={{ headerShown: true, headerTitle: 'Create An Account' }} />
</Stack.Navigator>
</NavigationContainer>
);
} else if (user)
return (
<NavigationContainer independent={true}>
<Stack.Navigator>
<Stack.Screen
name='Daily'
component={DailyScreen}
options={{ headerShown: false, headerBackVisible: false }} />
<Stack.Screen
name='Detail'
component={Detail}
options={{ headerShown: false, headerBackVisible: false }} />
</Stack.Navigator>
</NavigationContainer>
); return (
<NavigationContainer>
<App />
</NavigationContainer>
);
}
export default () => {
return (
<NavigationContainer independent={true}>
<App />
</NavigationContainer>
)
}
I want it to go to the DailyScreen page if the user has logged in before. But it always goes to the LoginScreen page.
Try this
change
const [user, setUser] = useState('');
to
const [user, setUser] = useState(null);
Why is it that when I navigate from the first screen to the second screen, there is a white blink on the left side of the screen?
https://imgur.com/mEKw9DH
first screen code:
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Cadastrar" component={Cadastrar} />
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
Second screen code:
const register = () => {
navigation.navigate("Cadastrar")
}
I have been struggling with this for days now... When I try to login it does not automatically navigate me to home screen, unless I close and open app.
I am working with 3 separate components. However after I register once, this issue doesn't occur it only happens with new accounts.
const [userAuth, setUserAuth] = useState()
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
user && auth.currentUser?.emailVerified ? setUserAuth(true) : setUserAuth(false)
})
return unsubscribe
})
return (
<Provider store={store}>
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen
name='main'
component={userAuth ? MainDrawer : AuthStack}
/>
</Drawer.Navigator>
</NavigationContainer>
</Provider>
This is my MainDrawer.js
export default function MainDrawer() {
return (
<Drawer.Navigator drawerContent={props => <DrawerScreen {...props} />}>
<Drawer.Screen
name='drawer'
component={HomeStack}
options={{ headerShown: false }}
/>
</Drawer.Navigator>
)
}
This is my HomeStack.js
<Stack.Navigator initialRouteName='home'>
<Stack.Screen name='home' component={TabNav}/>
<Stack.Screen name='about' component={AboutUs}/>
<Stack.Screen name='faq' component={FaqScreen}/>
<Stack.Screen name='userTerms' component={TermsScreen} />
<Stack.Screen name='privacy' component={PrivacyScreen} />
</Stack.Navigator>
I believe the issue is where you're trying to call onAuthStateChanged, it should be auth().onAuthStateChanged(...). Also, I would change it a little bit
useEffect(() => {
const unsubscribe = auth().onAuthStateChanged(firebaseUserResult => {
firebaseUserResult && firebaseUserResult.emailVerified ? setUserAuth(true) : setUserAuth(false)
})
return unsubscribe
})
I have a really strange problem and so far could not identify the possible weak points.
I have a firebase & react-native application with a nested login.
The problem is the navigation. The drawer and the stack navigation works fine, except for the login screen.
When I try to login and the isSignedIn variable becomes true, the screen is not changing for the home screen. It remains the login screen. However, on the console, I see the authentication was successful. If I go back to the code and click a save in the Navigation file (which was posted here), the forced reload seems to solve the problem and I can see the home screen. But this is not automatically.
So confused.
export default function Navigator() {
const user = firebase.auth().currentUser;
const [isSignedIn, setIsSignedIn] = useState(false)
useEffect( () => {
user ? setIsSignedIn(true) : setIsSignedIn(false)
if (isSignedIn) storeData(user)
})
const storeData = async (value) => {
try {
await AsyncStorage.setItem('userObject', JSON.stringify(value))
alert('Data successfully saved to the storage')
} catch (e) {
alert('Failed to save the data to the storage')
}
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
{isSignedIn ? (
<>
<Stack.Screen name='loggedInUserNavigationStack' component={loggedInUserNavigationStack} options={{headerShown: false}}>
</Stack.Screen>
</>
) : (
<Stack.Screen name="Log in" component={LoginScreen} options={{headerShown: false}} />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
function loggedInUserNavigationStack() {
return (
<Drawer.Navigator initialRouteName="mainContentNavigator" drawerContent={ props => <DrawerContent {...props} /> }>
<Drawer.Screen name="mainContentNavigator" component={mainContentNavigator} options={{ title: 'Home' }} />
<Drawer.Screen name="About" component={AboutScreen} options={{ title: 'About' }}/>
<Drawer.Screen name="Archive" component={ArchiveScreen} options={{ title: 'Archive' }}/>
<Drawer.Screen name="Profile" component={ProfileScreen} options={{ title: 'Profile' }} />
<Drawer.Screen name="Sign Out" component={SignOutScreen} options={{headerShown: false}}/>
</Drawer.Navigator>
);
}
function mainContentNavigator() {
return (
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen name="Home" component={HomeScreen} options={
({ navigation }) => {
return {
headerLeft: () => <Header navigation={navigation} />
}
}
} />
<Stack.Screen name="CertainHabbit" component={CertainHabbit} options={({ route }) => ({ title: route.params.name })} />
</Stack.Navigator>
);
}
Firebase automatically tries to restore the signed-in user when you load the page. But since this requires an async call to the server, it may take some time. Right now, by the time your const user = firebase.auth().currentUser runs, the user hasn't been authenticated yet. And by the time the authentication finishes, your code isn't aware of it.
The solution is to use an auth state listener, as shown in the first snippet of the documentation on determining the signed in user. For you that'd be something like this:
useEffect( () => {
firebase.auth().onAuthStateChanged((user) => {
setIsSignedIn(!!user);
if (user) storeData(user)
});
})
Please try,
<NavigationContainer>
<Stack.Screen name="Login" component={LoginScreen} options={{headerShown: false}} />
</NavigationContainer>
You have given initial route name has initialRouteName="Login"
I do see a space in the stack screen.
Try the following for return part:
return isSignedIn ? (
<NavigationContainer>
<Stack.Screen name='loggedInUserNavigationStack' component={loggedInUserNavigationStack} options={{headerShown: false}} />
</NavigationContainer>
):(
<NavigationContainer>
<Stack.Screen name="Login" component={LoginScreen} options={{headerShown: false}} />
</NavigationContainer>
)
I am trying to create a React Navigation drawer with custom content (I want to put profile information, probably not any links). I am having a ton of trouble doing so.
Here's my basic stack/drawer:
const Drawer = createDrawerNavigator();
function DrawerNav() {
return (
<ScrollView>
<DrawerItems {...props} />
<Text>Test Content</Text>
</ScrollView>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={Login} options={{
headerShown: false
}} />
<Stack.Screen name="Detail" component={Detail} />
<Stack.Screen name="Chat" component={Chat} />
<Stack.Screen name="Leagues" component={Leagues} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Home" component={Home} options={{
headerRight: (navigation) => (
<TouchableOpacity onPress={(navigation) => navigation.dispatch(DrawerActions.toggleDrawer())}>
<EvilIcons name="navicon" size={50} color="black" />
</TouchableOpacity>
),
headerLeft: () => (
null
),
}} />
<Stack.Screen name="CommForm" component={CommForm} />
</Stack.Navigator>
</NavigationContainer>
);
}
All I want, literally all I want, is a sidebar that I can toggle by pressing the <TouchableOpacity> button above with custom content inside of it.
I am able to do this with React Native Side Menu, but it seems like if I am using React Navigation, I should learn how to do it with this library, however it seems very difficult to do what I am trying to do.
How do I create a sidebar with custom content with React Navigation? I primarily want to use Stack navigation.
I would do something like this:
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItem label="..." />
// ...
</DrawerContentScrollView>
);
}
function StackNavigator({navigation}) {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={{
headerRight: () => (
<Button title="press" onPress={() => navigation.toggleDrawer()} />
),
}}
/>
// Your other screens...
</Stack.Navigator>
);
}
function DrawerNavigator({navigation, route}) {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Stack" component={StackNavigator} />
</Drawer.Navigator>
);
}
const App = () => {
return (
<NavigationContainer>
<DrawerNavigator />
</NavigationContainer>
);
};
So you can set the drawer navigation to be your main navigator and your stack navigation to be a screen of the drawer navigation. This way you can toggle the drawer without first navigating to it.
For creating custom drawer content you can pass a component to the drawerContent on the drawer navigator.
If you're going to use DrawerContentScrollView and/or DrawerItem like I've done in this example, be sure to import it from '#react-navigation/drawer'; .
Look at the documentation for more information https://reactnavigation.org/docs/drawer-navigator/#providing-a-custom-drawercontent.