Issues with header button in React Native Expo - javascript

I want to insert a header button for user to be able to sign out easily but I am having trouble with it.
I am referring to https://reactnavigation.org/docs/header-buttons
Within my app.js
import { StatusBar } from 'expo-status-bar';
import React from 'react'
import { signOut } from 'firebase/auth';
import { auth } from '../firebase';
import { StyleSheet, Text, View, Button } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
import RegisterScreen from './screens/RegisterScreen';
import ForgetPasswordScreen from './screens/ForgetPasswordScreen';
import SubScreen1 from './screens/SubScreen1';
const Stack = createNativeStackNavigator();
const handleSignOut = async () =>{
try{
await signOut(auth)
console.log("Signed out successfully")
navigation.replace("Login")
}catch (error) {
console.log({error});
}
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen options= {{ headerShown : false }} name="Login" component={LoginScreen} />
<Stack.Screen name="Home" component={HomeScreen} options={{headerRight: () => (
<Button
onPress={handleSignOut}
title="Sign Out"
color="#0782F9" /> ),}} />
<Stack.Screen name="Register" component={RegisterScreen} />
<Stack.Screen name="Forget Password" component={ForgetPasswordScreen} />
<Stack.Screen name="SubScreen1" component={SubScreen1} options={{ title: 'Search Result' }}/>
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
The button seems to appear but I cannot use it at all. It seems this line import { auth } from '../firebase'; is giving me issue. But I don't get it why. I used the same exact line in my home screen, login screen and register screen and it all worked.
import { auth } from '../firebase'; gives me the error of Unable to resolve "../firebase" from "App.js"
I searched online and tried import { auth } from 'firebase/app' gives me the error of {"error": [TypeError: undefined is not an object (evaluating 'util.getModularInstance(auth).signOut')]}
My directory to firebase: Projects/FYPAPP/node_modules/firebase
Under the firebase.js

Related

expo app error when creating stack navigator

I keep getting the error when I write this:
const Stack = createStackNavigator();
i have installed everything required for it but it gives me this error
undefined is not an object (evaluating 'Object.keys(routeConfigs)')
Here is my code:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {Home} from './screens/homepage/home';
import { useFonts } from 'expo-font';
import { NavigationContainer, StackActions } from '#react-
navigation/native';
import { createStackNavigator } from 'react-navigation-stack';
export default function App() {
function HomeScreen() {
return(
<View>
<Text>Hello</Text>
</View>
)
}
const Stack = createStackNavigator();
let [fontsLoaded] = useFonts({
'Main': require('./assets/century.ttf'),
'Main-Bold': require('./assets/century-bold.ttf')
});
if(!fontsLoaded) {
return <Text>Waiting...........</Text>
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen style={styles.container} name="Home" component=
{HomeScreen}/>
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
height:'100%',
backgroundColor:'#141F2B',
},
});
try installing #react-navigation/stack and #react-navigation/native, then try doing this:
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer } from "#react-navigation/native";
const Stack = createStackNavigator();
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
style= {styles.container}
name= "Home"
component= {HomeScreen}
/>
</Stack.Navigator>
</NavigationContainer>

The action 'NAVIGATE' with payload {...} was not handled by any navigator

So I'm building an app where i send notification to the user when there's an update. Once the user receives it, on clicking, I want to navigate to a specific screen in my app.
The problem is, to do that I have to use a navigation reference to be able to access the navigation object. I did read the doc, but once applying it I get the following error:
The action 'NAVIGATE' with payload {"name":"HomeScreen","params":{"userName":"Lucy"}} was not handled by any navigator.
Do you have a screen named 'HomeScreen'?
RootNavigation.js:
import * as React from 'react';
import { createNavigationContainerRef } from '#react-navigation/native';
export const navigationRef = createNavigationContainerRef()
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
}
App.js:
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import AppNavigator from "./app/navigation/AppNavigator";
import { NavigationContainer } from "#react-navigation/native";
import {navigationRef} from "./app/navigation/rootNavigation";
export default function App() {
return (
<AuthContext.Provider>
<NavigationContainer ref={navigationRef}>
<AppNavigator />
</NavigationContainer>
</AuthContext.Provider>
);
}
AppNavigator.js:
import React, {useEffect, useContext} from "react";
import HomeScreen from "../screens/Home/HomeScreen";
import DashboardScreen from "../screens/Home/DashboardScreen";
import { createDrawerNavigator } from "#react-navigation/drawer";
import FolderNavigator from "./FolderNavigator";
import * as Notifications from "expo-notifications";
import * as RootNavigation from "./rootNavigation";
import AuthNavigator from "./AuthNavigator";
const Drawer = createDrawerNavigator();
const AppNavigator = ({}) => {
useEffect(() =>{
registerForPushNotifications()
Notifications.addNotificationReceivedListener(notification =>{
RootNavigation.navigate('HomeScreen', { userName: 'Lucy' });
})
},[])
const registerForPushNotifications = async ( ) => {
try {
const permissions = await Notifications.getPermissionsAsync();
if (!permissions.granted) return;
/*const token = await Notifications.getExpoPushTokenAsync()*/
const token = (await Notifications.getExpoPushTokenAsync()).data;
/*await expoPushTokenApi.register(token, user.guid)*/
/*console.log(token)*/
} catch (error){
console.log(error)
}
};
return (
<Drawer.Navigator>
<Drawer.Screen
name="Dashboard"
component={DashboardScreen}
/>
<Drawer.Screen
name="Liste des dossiers"
component={FolderNavigator}
/>
<Drawer.Screen
name="Liste des clients"
component={HomeScreen}
/>
</Drawer.Navigator>
)};
export default AppNavigator;
FolderNavigator.js:
import React from "react";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import HomeScreen from "../screens/Home/HomeScreen";
import FolderDetails from "../screens/FolderDetails";
const Stack = createNativeStackNavigator();
const FolderNavigator = () => (
<Stack.Navigator>
<Stack.Screen
name="Liste des dossiers"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Détails"
component={FolderDetails}
options={{ headerTitle: "", headerBackTitle: "" }}
/>
</Stack.Navigator>
);
export default FolderNavigator;
Directory structure:
This line RootNavigation.navigate('HomeScreen', { userName: 'Lucy' }) is causing the error, because when setting up your navigation, you didn't name any screen HomeScreen, I'm talking about Stack.Screen's name property and Drawer.Screen's name property.

When trying to insert a Custom Font in Expo using AppLoading, I get Syntax Error "None of these files exist"

I am trying to insert a custom font into React Native Expo. I am using the AppLoading method. For some reason, I get an error message saying "None of these files exist"
...even though the file clearly does exist in the file directory:
My Expo version is 5.4.0. I've looked for similar questions, but they either don't involve fonts, or they are using font Async rather than AppLoading.
This is my full code below.
import 'react-native-gesture-handler';
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import HomeScreen from './src/screens/HomeScreen';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import { Font } from 'expo';
const Stack = createStackNavigator();
export default function App() {
let [fontsLoaded] = useFonts({
'SEGOEUI': require('./assets/fonts/SEGOEUI.TTF'),
});
if (!fontsLoaded) {
return <AppLoading />;
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home" screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

React Native and firebase Authentication navigation

I am trying to do user authentication using Firebase + Expo.
Currently working on the Authentication flows, but I keep getting this error that i can't seem to fix :(
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {login} from './login';
import {pageOne} from './pageOne';
import {pageTwo} from './pageTwo';
import 'react-native-gesture-handler';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import {firebase} from './fbConfig';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
export default function App() {
return (
firebase.auth().onAuthStateChanged((authenticate)=>{
if (authenticate) {
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="PageOne"
component={pageOne}
/>
<Tab.Screen
name="PageTwo"
component={pageTwo}
/>
</Tab.Navigator>
</NavigationContainer>
} else
{
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Login"
component={login}
/>
</Stack.Navigator>
</NavigationContainer>
}
})
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Its currently showing an error:
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
It is because the React is expecting a component to be returned from the App function but here you are returning the firebase.auth().onAuthStateChanged() which ultimately does not return any component. It(onAuthStateChanged) helps to register a listener for user's auth state change and returns a method to unsubscribe from the firebase auth listener on the component unmount(or whenever you would like to remove the auth state listener).
You can check this link for more details.
In your example, you can do it something like:
import React, {useState} from 'react';
import { StyleSheet} from 'react-native';
import { login } from './login';
import { pageOne } from './pageOne';
import { pageTwo } from './pageTwo';
import 'react-native-gesture-handler';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { firebase } from './fbConfig';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
export default function App() {
const [initializing, setInitializing] = useState(true);
const [user, setUser] = useState();
function onAuthStateChanged(user) {
setUser(user);
if (initializing) setInitializing(false);
}
useEffect(() => {
const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged);
return subscriber; // unsubscribe on unmount
}, []);
if (initializing) return null;
if (!user) {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Login"
component={login}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="PageOne"
component={pageOne}
/>
<Tab.Screen
name="PageTwo"
component={pageTwo}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

React Native "TypeError: Object(...) is not a function" Error for react navigation stack

I'm having an issue with my react-navigation-stack, I believe it could be a problem with dependencies, but I'm not sure if that's it. I am simply trying to have some text redirect to another page. If there is code that is irrelevant to the issue, such as a button, I apologize as I am trying to learn react native. The problem is being pointed at homeStack.js at the first import, "import { createStackNavigator } from '#react-navigation/stack';" , but previously I just used react-navigation-stack there, which I believe was a part of old dependencies, but it gave me a module not found error at first, which changed to what I have now when I put #react-navigation/stack instead. I was learning from a video tutorial, but the code from the tutorial was not compiling. I redownloaded react navigation multiple times and have tried some thing that did not work. I will post my code below and would really appreciate help and input as to what can help my problem. Thanks you!
Picture of error
homeStack.js
import { createStackNavigator } from '#react-navigation/stack';
//import { createAppContainer } from '#react-navigation/native';
//import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from '../screens/home';
import ReviewDetails from '../screens/reviewDetails';
const screens = {
Home: {
screen: Home,
},
ReviewDetails: {
screen: ReviewDetails,
},
};
// home stack navigator screens
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
home.js
import React from 'react';
import { StyleSheet, View, Text, } from 'react-native';
import { globalStyles } from '../styles/global';
export default function Home() {
return (
<View style={globalStyles.container}>
<Text style={globalStyles.titleText}>Home Screen</Text>
</View>
);
}
App.js
//import React from 'react';
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import Buttonwithbackground from './src/Buttonwithbackground';
import { StackNavigator } from 'react-navigation';
//import Expo from 'expo';
//import Screen from 'screen2';
import { AppLoading } from 'expo';
import Navigator from './routes/homeStack';
import { render } from 'react-dom';
//
//import {Link} from 'react-router-dom';
class HomeScreen extends React.Component{
static NavigationOptions = {
title: 'Home',
};
render(){
const { navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Text
onPress= { ()=> navigate('Home') }>Navigate to Profile
</Text>
</View>
);
}
}
class ProfileScreen extends React.Component{
static NavigationOptions = {
title: 'Profile',
};
render(){
const { navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Text
onPress= { ()=> navigate('Profile') }>Navigate to Profile
</Text>
</View>
);
}
}
//export default function App() {
export default class App extends Component {
editUser = () => {
this.props.navigation.navigate("Screen");
// this.navigation.navigate("screen2");
// window.location.href = 'screen2';
};
editUser2 = () => {
//if the second button is clicked, it will redirect to yahoo.com
window.location.href="http://yahoo.com"
};
render(){
return (
<View style={styles.container}>
<Image
style={{width: 350, height: 200}}
source = {require('./assets/dolanduckjoker.jpg')}
/>
<Navigator />
<Buttonwithbackground text='Login' color='black' onPress={this.editUser2}/>
<p><br/></p>
<Button title='Login' color='black' onPress={this.editUser2}/>
<Button title='Login' color='black' onPress={() => navigation.navigate('screen2.js')}/>
<p><br/></p>
<Button
style={styles.cancelButton}
onPress={this.editUser}
title="Register"
color="#343434"
accessibilityLabel="Register a User."/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 32,
textAlign: 'center',
margin: 10,
},
});
The error says what's wrong -
Object(...) is not a function
createStackNavigator expects a function and you are passing an object to it as a parameter. According to docs
Your code should look like -
import { createStackNavigator } from '#react-navigation/stack';
//import { createAppContainer } from '#react-navigation/native';
//import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from '../screens/home';
import ReviewDetails from '../screens/reviewDetails';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="ReviewDetails" component={ReviewDetails} />
</Stack.Navigator>
);
}
export default MyStack; //you need to render this
Now in your root file, It should be something like this (excluding your additional code) -
import { createStackNavigator } from '#react-navigation/stack';
import MyStack from "yourPath";
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}

Categories