Firebase signinwithemail&password is not a function - javascript

I recently have been making a app for my IOS app and am introducing firebase email/password auth to my project. The registration part works good but when i do the handleSignin function it doesnt quite work as expected. Any ideas why
my code:
import React from 'react';
import { Button,StyleSheet,View,Text, Image,SafeAreaView, TextInput, KeyboardAvoidingView, TouchableOpacity} from 'react-native';
import {auth} from "../firebase"
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword} from "firebase/auth";
import { FirebaseError } from 'firebase/app';
export const Login = () => {
const [email, setEmail] = React.useState("")
const [password, setPassword] = React.useState("")
const handleSignUp = (e) => {
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ..
});
}
const handleLogin = () => {
auth
.signInWithEmailAndPassword(email, password)
.then(userCredentials => {
const user = userCredentials.user;
console.log('Logged in with:', user.email);
})
.catch(error => alert(error.message))
}
return (
<KeyboardAvoidingView
style={styles.container}
behavior="padding"
>
<Text style={styles.heading}>Unlock the power of time managment</Text>
<View style={styles.inputContainer}>
<TextInput
value={email}
placeholder="Email"
style={styles.input}
onChangeText={text => setEmail(text)}
/>
<TextInput
placeholder="Password"
style={styles.input}
onChangeText={text => setPassword(text)}
value={password}
secureTextEntry
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={handleLogin}
>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.buttonOutline]}
onPress={handleSignUp}
>
<Text style={styles.buttonOutlineText} >Register</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
inputContainer: {
width: '80%'
},
input: {
backgroundColor: 'white',
paddingHorizontal: 15,
paddingVertical: 10,
borderRadius: 10,
marginTop: 5,
},
heading: {
fontSize: 30,
fontWeight: "700"
},
buttonContainer: {
width: '60%',
justifyContent: 'center',
alignItems: 'center',
marginTop: 40,
},
button: {
backgroundColor: '#0782F9',
width: '100%',
padding: 15,
borderRadius: 10,
alignItems: 'center',
},
buttonOutline: {
backgroundColor: 'white',
marginTop: 5,
borderColor: '#0782F9',
borderWidth: 2,
},
buttonText: {
color: 'white',
fontWeight: '700',
fontSize: 16,
},
buttonOutlineText: {
color: '#0782F9',
fontWeight: '700',
fontSize: 16,
},
});
expo go error:
firebase.auth.signinwithemailandpassword not a function
firebase.auth.signinwithemailandpassword returned undefined

You're using the new, modular SDK syntax, where most functionality is exposed as a top-level function, instead of as a method on an object. When you call createUserWithEmailAndPassword as a top-level function you pass in the auth object, and you need to do the same for signing in:
const handleLogin = () => {
signInWithEmailAndPassword(auth, email, password)
...
I recommend keeping the Firebase documentation handy when troubleshooting problems like this, as the above is almost exactly the code shown in the Web version 9 (modular) tab in the section signing in a user with an email address and password

Below is the guideline on what worked for me, you can try it.
Here is the explanation:
You have to import signInWithEmailAndPassword from firebase/auth.
Note: signInWithEmailAndPassword is a function that takes three arguments, ie auth, email and password.
import { signInWithEmailAndPassword } from "firebase/auth";
const signIn= (e) => {
e.preventDefault();
// for login
signInWithEmailAndPassword(auth, email, password).then((auth) => {
console.log(auth);
if (auth) {
// if successfully signed in, redirect the new user to the home page
navigate('/');
}
}).catch(error => alert(error.message));
};

Related

Using Firebase Google Authentication with React Native

I have been encountering an error when trying to use Firebase's SignIn With google auth method. So far I have:
Enabled the google auth method in my admin console
Looked at the docs for it and implemented the requirements
Enabled, and correctly got the Email/Password auth to work
I am trying to use the signInWithPopup method instead of a redirect.
Here is the SignIn.js code file:
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, TextInput, Pressable } from 'react-native';
import tw from 'tailwind-react-native-classnames';
import { signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
import { auth, provider } from "../firebaseConfig";
import { Ionicons } from '#expo/vector-icons';
import { Feather } from '#expo/vector-icons';
import SignInHeader from '../components/SignInHeader';
export default function SignIn({ navigation }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
let signInWithGoogle = () => {
signInWithPopup(auth, provider)
.then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
const user = result.user;
navigation.navigate("Home");
console.log(user);
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
const email = error.customData.email;
const credential = GoogleAuthProvider.credentialFromError(error);
console.log(errorCode, errorMessage, email, credential);
});
}
let signIn = () => {
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
const user = userCredential.user;
navigation.navigate("Home");
console.log(user);
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.log(errorCode, errorMessage);
switch (errorCode) {
case "auth/invalid-email":
alert("Please Enter a valid email address");
break;
case "auth/user-not-found":
alert("User not found");
break;
case "auth/wrong-password":
alert("Incorrect Password. Try again.");
break;
case "auth/internal-error":
alert("Please enter a valid password");
break;
}
});
}
return (
<>
<SignInHeader />
<View style={{ alignItems: 'center', marginTop: '25%', paddingTop: 10 }}>
<View style={styles.searchSection}>
<Ionicons name="mail-outline" size={20} color="black" style={styles.searchIcon} />
<TextInput
style={styles.input}
placeholder="Email"
onChangeText={text => setEmail(text)}
value={email}
clearButtonMode="always"
/>
</View>
<View style={{ padding: 25 }}>
<View style={styles.searchSection}>
<Feather name="lock" size={20} color="black" style={styles.searchIcon} />
<TextInput
style={styles.input}
placeholder="Password"
onChangeText={text => setPassword(text)}
value={password}
secureTextEntry={true}
clearButtonMode="always"
/>
</View>
</View>
<Pressable style={{ marginLeft: '55%', marginTop: -10 }} onPress={() => navigation.navigate("ResetPassword")}>
<Text style={{ color: '#cdcdcd' }}>Forgot Password?</Text>
</Pressable>
<Pressable onPress={signIn} style={({ pressed }) => [
{
backgroundColor: pressed
? '#34AE65'
: '#64DA93'
},
styles.notPressed,
]}>
<Text style={{ fontFamily: "OpenSans_600SemiBold", fontSize: 20, color: 'white' }}>Log In</Text>
</Pressable>
<Pressable onPress={signInWithGoogle} style={({ pressed }) => [
{
backgroundColor: pressed
? '#34AE65'
: '#64DA93'
},
styles.notPressed,
]}>
<Text style={{ fontFamily: "OpenSans_600SemiBold", fontSize: 20, color: 'white' }}>Log In with Google</Text>
</Pressable>
<Pressable onPress={() => navigation.navigate("SignUp")}>
<Text style={{ flex: 1, color: '#cdcdcd', marginTop: 20, flexDirection: 'row' }}>Don't have and account?<Text style={{ color: 'grey' }}> Sign Up</Text></Text>
</Pressable>
</View >
</>
);
}
const styles = StyleSheet.create({
searchSection: {
flexDirection: 'row',
alignItems: 'center',
width: 360,
height: 45,
borderBottomColor: '#64DA93',
borderBottomWidth: 2,
},
searchIcon: {
padding: 1,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 10,
},
notPressed: {
height: 45,
width: 360,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
marginTop: 50
}
});
Next, which is important is my firebaseConfig.js code file:
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
const firebaseConfig = {
apiKey: "xx",
authDomain: "xx",
projectId: "xx",
storageBucket: "xx",
messagingSenderId: "xx",
appId: "xx",
measurementId: "xx"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth();
const provider = new GoogleAuthProvider();
export { auth, provider };
This is the error:
ERROR TypeError: (0, _auth.signInWithPopup) is not a function. (In '(0, _auth.signInWithPopup)(_firebaseConfig.auth, _firebaseConfig.provider)', '(0, _auth.signInWithPopup)' is undefined)
Thanks for the help.
signInWithPopup is not supported in React Native. Use auth().signInWithCredential(googleCredential) instead.
Upon successful sign-in, any onAuthStateChanged listeners will trigger with the new authentication state of the user.
Consider using this library instead as the one you are using is really meant for the web

Firebase error when calling a displayName

I am having issues when a user signs up using firebase auth, I am unable to capture the username so that it can be used in other parts of the app.
The error that i see in the console is:
"Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field displayName in document"...)
Would really appreciate if someone can point me to where the mistake is. Here are my files:
AuthProvider.js
import React, { createContext, useState } from "react";
import { auth, db } from "../firebase";
export const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
return (
<AuthContext.Provider
value={{
user,
setUser,
login: async (email, password) => {
try {
await auth.signInWithEmailAndPassword(email, password);
} catch (e) {
console.log(e);
}
},
register: async (email, password, display_name) => {
try {
await auth
.createUserWithEmailAndPassword(email, password)
.then(async (res) => {
const userInfo = {
displayName: display_name,
};
await db
.collection("users")
.doc(res.user.uid)
.set(userInfo)
.then(() => {
console.log("user added")
console.log(res);
});
});
} catch (e) {
console.log(e);
}
},
logout: async () => {
try {
await auth.signOut();
} catch (e) {
console.log(e);
}
},
}}
>
{children}
</AuthContext.Provider>
);
};
SignUpScreen.js
import React, { useContext, useState } from "react";
import {
View,
Text,
TouchableOpacity,
Image,
Platform,
StyleSheet,
ScrollView,
Alert,
} from "react-native";
import FormInput from "../components/FormInput";
import FormButton from "../components/FormButton";
import SocialButton from "../components/SocialButton";
import { AuthContext } from "../navigation/AuthProvider";
const SignupScreen = ({ navigation }) => {
const [display_name, setDisplay_Name] = useState();
const [email, setEmail] = useState();
const [password, setPassword] = useState();
const [confirmPassword, setConfirmPassword] = useState();
const { register } = useContext(AuthContext);
const registerCheck = () => {
if (
display_name != "" &&
email != "" &&
password != "" &&
confirmPassword != ""
) {
if (password == confirmPassword) {
register(email, password);
} else {
Alert.alert("Oops! Passwords did not match");
}
} else {
Alert.alert("Oops! Some information is missing");
}
console.log(display_name, email, password, confirmPassword);
};
return (
<ScrollView contentContainerStyle={styles.container}>
<Text style={styles.text}>Create an Account</Text>
<FormInput
labelValue={display_name}
onChangeText={(userDisplay_Name) => setDisplay_Name(userDisplay_Name)}
placeholderText="Name"
iconType="user"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
<FormInput
labelValue={email}
onChangeText={(userEmail) => setEmail(userEmail)}
placeholderText="Email"
iconType="user"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
<FormInput
labelValue={password}
onChangeText={(userPassword) => setPassword(userPassword)}
placeholderText="Password"
iconType="lock"
secureTextEntry={true}
/>
<FormInput
labelValue={confirmPassword}
onChangeText={(userConfirmPassword) =>
setConfirmPassword(userConfirmPassword)
}
placeholderText="Confirm Password"
iconType="lock"
secureTextEntry={true}
/>
<FormButton
buttonTitle="Sign Up"
onPress={() => registerCheck(email, password)}
/>
<View style={styles.textPrivate}>
<Text style={styles.color_textPrivate}>
By registering, you confirm that you accept our{" "}
</Text>
<TouchableOpacity onPress={() => alert("Terms Clicked!")}>
<Text style={[styles.color_textPrivate, { color: "#e88832" }]}>
Terms of service
</Text>
</TouchableOpacity>
<Text style={styles.color_textPrivate}> and </Text>
<Text style={[styles.color_textPrivate, { color: "#e88832" }]}>
Privacy Policy
</Text>
</View>
<SocialButton
buttonTitle="Sign Up with Facebook"
btnType="facebook"
color="#4867aa"
backgroundColor="#e6eaf4"
onPress={() => {}}
/>
<SocialButton
buttonTitle="Sign Up with Google"
btnType="google"
color="#de4d41"
backgroundColor="#f5e7ea"
onPress={() => {}}
/>
<TouchableOpacity
style={styles.navButton}
onPress={() => navigation.navigate("Login")}
>
<Text style={styles.navButtonText}>Have an account? Sign In</Text>
</TouchableOpacity>
</ScrollView>
);
};
export default SignupScreen;
const styles = StyleSheet.create({
container: {
backgroundColor: "#f9fafd",
flex: 1,
justifyContent: "center",
alignItems: "center",
padding: 20,
},
text: {
fontFamily: "Helvetica",
fontSize: 28,
marginBottom: 10,
color: "#051d5f",
},
navButton: {
marginTop: 15,
},
navButtonText: {
fontSize: 18,
fontWeight: "500",
color: "#2e64e5",
fontFamily: "Helvetica",
},
textPrivate: {
flexDirection: "row",
flexWrap: "wrap",
marginVertical: 35,
justifyContent: "center",
},
color_textPrivate: {
fontSize: 13,
fontWeight: "400",
fontFamily: "Helvetica",
color: "grey",
},
});

Integrating Deso Identity into React Native App - retrieve user data from Deso Identity API call

I'm new to React Native and currently trying to integrate Deso Identity into my React Native App.
Question: How should I retrieve user data if I use WebView and what is the correct implementation to generate derived key?
Goal:
Navigate to Deso Identity Page when clicking on a button from LogIn screen
Receive derived key and all user response data after logging in
What I have tried:
I'm currently trying to generate derive key by making a call to Deso's window API without using WebView
I have tried using WebView with a DesoLogin.js component below but there's not much details from Deso's documentation and I was not able to retrieve response data after logging in
DesoLogin.js
import React, { useState, useEffect } from 'react';
import { WebView, WebViewNavigation } from 'react-native-webview';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useNavigation } from '#react-navigation/native';
import Home from '../screens/Home';
const DesoLogin = () =>{
const navigation = useNavigation();
// const webView = WebView();
const [signIn, setSignIn] = useState(false)
const [userProfile, setUserProfile] = useState(null)
// function onMessage(data) {
// alert(data.nativeEvent.data);
// }
// const handleLogin = (e) => {
// const data = webView.getUrl(e);
// setUserProfile(data)
// }
const handleNavigationStateChange = () => {
navigation.navigate("Home", {userProfile});
}
const onNavigationStateChange = e => {
if (userProfile!==e.url) {
console.log(e.url);
setUserProfile(e.url);
console.log(userProfile);
}
};
useEffect(() => {
setSignIn(true);
if (userProfile) {
handleNavigationStateChange();
}
},[userProfile])
return (
<SafeAreaView style={{ flex: 1 }}>
<WebView
source={{
uri: 'https://identity.deso.org/derive?callback=auth://derive'
}}
// onMessage={onMessage}s
// injectedJavaScript={handleLogin}
onNavigationStateChange={onNavigationStateChange}
javaScriptEnabled
style={{ marginTop: 20 }}
/>
</SafeAreaView>
);
}
export default DesoLogin;
Error:
I know that windows.open() doesn't work in react native like it does in web application
Deso Mobile Integration Doc
Window API-Callbacks section
Login.js Screen code below
import React, { useEffect, useState } from "react";
import { useNavigation } from "#react-navigation/native";
import axios from 'axios';
import DesoLogin from "../components/DesoLogin";
import DesoIdentity from "../libs/DesoIdentity";
import { KeyboardAvoidingView, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
import { COLORS, FONTS, SIZES, SHADOWS, assets } from "../constants";
import { CircleButton, RectButton, DetailsDesc, DetailsBid, FocusedStatusBar } from "../components";
const LogIn = () => {
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [publicKey, setSetPublicKey] = useState(null)
const [desoIdentity, setDesoIdentity] = useState(null)
const navigation = useNavigation()
useEffect(() => {
axios('https://identity.deso.org/derive?callback=auth://derive')
.then(response => {
setSetPublicKey(response.accessSignature)
})
.catch(error => {
console.error("Error Fetching data", error);
setError(error);
throw error;
})
} , [])
const handleSignUp = () => {
return 0;
}
const handleLogin = async () => {
setSetPublicKey(publicKey);
setLoggedIn(true);
}
const handleLogout = () => {
setSetPublicKey(null);
setLoggedIn(false);
}
return (
<KeyboardAvoidingView
style={styles.container}
behavior="padding"
>
<View style={styles.inputContainer}>
<TextInput
placeholder="Email"
value={email}
onChangeText={text => setEmail(text)}
style={styles.input}
/>
<TextInput
placeholder="Password"
value={password}
onChangeText={text => setPassword(text)}
style={styles.input}
secureTextEntry
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity
onPress={handleLogin}
style={styles.button}
>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<TouchableOpacity
// onPress={handleSignUp}
style={[styles.button, styles.buttonOutline]}
>
<Text style={styles.buttonOutlineText}>Register</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
)
}
export default LogIn;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
inputContainer: {
width: '80%'
},
input: {
backgroundColor: COLORS.white,
paddingHorizontal: 15,
paddingVertical: 10,
borderRadius: 10,
marginTop: 5,
},
buttonContainer: {
width: '60%',
justifyContent: 'center',
alignItems: 'center',
marginTop: 40,
},
button: {
backgroundColor: '#0782F9',
width: '100%',
padding: 15,
borderRadius: 10,
alignItems: 'center',
},
buttonOutline: {
backgroundColor: COLORS.white,
marginTop: 5,
borderColor: '#0782F9',
borderWidth: 2,
},
buttonText: {
color: COLORS.white,
fontWeight: '700',
fontSize: 16,
},
buttonOutlineText: {
color: '#0782F9',
fontWeight: '700',
fontSize: 16,
},
})

Firestore "get" function getting executed multiple times

I'm a newbie at React-Native and Firebase and i'm using Firebase Cloud Firestore for a project. I'm trying to get filtered data from the database statically (as i'm learning to use it for now), but somehow my function is getting executed multiple times, the numbers of readings is increasing rapidly and i'm having some random errors too. I would like to know what's wrong.
Here is my code for the file that only deals with the database (Firestore.js):
import React, { useState, useEffect } from "react";
import { ActivityIndicator } from "react-native";
import * as firebase from "firebase";
import "firebase/firestore";
function onResult(QuerySnapshot) {
console.log("Pegamos a coleção de Animais.");
}
function onError(error) {
console.error(error);
}
export function GetAnimalsByEspecie(especie) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
console.log("entrou Especie");
const subscriber = firebase
.firestore()
.collection("Animal")
.where("especie", "==", especie)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
export function GetAnimalsByNome(nomeAnimal) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
console.log("entrou nome nooome");
const subscriber = firebase
.firestore()
.collection("Animal")
.where("nome", "==", nomeAnimal)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
export default function GetAnimals() {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
useEffect(() => {
console.log("entrou listener");
const subscriber = firebase
.firestore()
.collection("Animal")
// .where('')
.onSnapshot((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
return () => subscriber();
}, []);
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
Here is my code for the file that displays data on the screen (index.js):
import React, { useState } from "react";
import {
View,
Text,
KeyboardAvoidingView,
StyleSheet,
Image,
TextInput,
TouchableHighlight,
ScrollView,
Button,
ActivityIndicator,
FlatList,
} from "react-native";
import { SearchBar } from "react-native-elements";
import { createStackNavigator } from "#react-navigation/stack";
import { SafeAreaView } from "react-native-safe-area-context";
import SubmitButton from "../../shared/SubmitButton";
import FocusAwareStatusBar from "../../shared/StatusBar";
import GetAnimals, {GetAnimalsByEspecie, GetAnimalsByNome} from "../../db/Firestore";
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: "#fafafa",
alignItems: "center",
justifyContent: "center",
},
regform: {
alignSelf: "stretch",
},
textInput: {
fontFamily: "Roboto_400Regular",
fontSize: 14,
alignSelf: "stretch",
paddingLeft: 12,
marginHorizontal: 16,
color: "#000000",
borderBottomColor: "#dcdcdc",
borderBottomWidth: 0.8,
paddingBottom: 8,
},
label: {
alignSelf: "stretch",
marginTop: 28,
marginBottom: 32,
paddingLeft: 28,
color: "#589b9b",
},
container: {
flex: 1,
justifyContent: "center",
alignSelf: "center",
height: 128,
width: 128,
backgroundColor: "#fff",
elevation: 4,
},
button: {
alignItems: "center",
backgroundColor: "#f1f2f2",
paddingTop: 44,
paddingBottom: 48,
},
infobox: {
backgroundColor: "#cfe9e5",
borderRadius: 4,
height: 80,
width: 328,
marginTop: 16,
marginHorizontal: 16,
justifyContent: "space-evenly",
alignContent: "center",
},
infotext: {
fontFamily: "Roboto_400Regular",
fontSize: 14,
color: "#434343",
paddingHorizontal: 15,
marginVertical: 11,
textAlign: "center",
},
});
export default function Animais() {
var animais = GetAnimalsByEspecie('shitzu');
const search = () => {
const [searchQuery, setSearchQuery] = useState("");
return (
<SearchBar
placeholder="Escreva aqui..."
onChangeText={""}
value={searchQuery}
/>)
};
return (
<SafeAreaView style={{ flex: 1 }}>
<FocusAwareStatusBar barStyle="light-content" backgroundColor="#88c9bf" />
<KeyboardAvoidingView style={styles.background}>
<View>
<Text>Animais</Text>
<FlatList
ListHeaderComponent={''}
data={animais}
renderItem={({ item }) => (
<View
style={{
height: 50,
width: 350,
flex: 1,
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Animal ID: {item.id}</Text>
<Text>Animal Name: {item.nome}</Text>
</View>
)}
/>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
I'm not using SearchBar yet, for now i'm just trying to fetch and display the data which have 'especies' field equal to 'shitzu' from the database. Sometimes I get the correct information, sometimes I get errors.
Thanks for the help.
You should put your fetches inside of a useEffect so you can make it run only once. Otherwise, when your fetch callbacks set state, you'll get a re-render, and your fetch code will run again. Also, it looks like GetAnimalsByEspecie, since it invokes hooks, should itself be a hook. For example:
export function useAnimalsByEspecie(especie) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
useEffect(() => {
const subscriber = firebase
.firestore()
.collection("Animal")
.where("especie", "==", especie)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
}, [especie]);
return [animais, loading];
}
...which would be used like:
function Animais() {
var [animais, isLoading] = useAnimalsByEspecie('shitzu');
const search = () => {
const [searchQuery, setSearchQuery] = useState("");
return (
<SearchBar
placeholder="Escreva aqui..."
onChangeText={""}
value={searchQuery}
/>)
};
if (isLoading) {
return <ActivityIndicator />;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<FocusAwareStatusBar barStyle="light-content" backgroundColor="#88c9bf" />
<KeyboardAvoidingView style={styles.background}>
<View>
<Text>Animais</Text>
<FlatList
ListHeaderComponent={''}
data={animais}
renderItem={({ item }) => (
<View
style={{
height: 50,
width: 350,
flex: 1,
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Animal ID: {item.id}</Text>
<Text>Animal Name: {item.nome}</Text>
</View>
)}
/>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}

Getting error "undefined is not an object(evaluating 'navigation.navigate')" after firebase auth - react native

Hi I'm getting the error undefined is not an object(evaluating 'navigation.navigate') after I'm submitting the form. I searched many google/stackoverflow answers but none of them helped me.
I'm not sure if this is cause by firebase or actual prop navigation. Any insights on this ???
Please see the code below:
// parent component
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import LoginForm from '../components/LoginForm';
const Login = () => {
return (
<View style={styles.mainWrapper}>
<Image style={styles.logo} title="Logo" source={require('../assets/box.png')}/>
<LoginForm/>
</View>
);
}
const styles = StyleSheet.create({
logo: {
width: 150,
height: 150,
marginTop: 55
},
mainWrapper: {
display: "flex",
alignItems: "center"
}
});
export default Login;
// login form component
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity, Alert} from 'react-native';
import firebase from 'firebase/app';
import 'firebase/auth';
import { firebaseConfig } from '../config';
if(!firebase.apps.length){
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
}
const auth = firebase.auth();
const LoginForm = ({navigation}) => {
const [email,setEmail] = useState('');
const [password, setPassword] = useState('');
const signIn = async() => {
try {
let response = await auth.signInWithEmailAndPassword(email,password);
if(response.user){
Alert.alert('logged in' + response.user.email);
navigation.navigate('Driver');
}
}catch(e){
Alert.alert(e.message);
}
};
return (
<View style={styles.formView}>
<TextInput
value={email}
placeholder="Email"
style={styles.input}
onChangeText={userEmail => setEmail(userEmail)}
autoCapitalize='none'
keyboardType='email-address'
autoCorrect={false}
/>
<TextInput
value={password}
placeholder="Password"
secureTextEntry={true}
style={styles.input}
onChangeText={userPassword => setPassword(userPassword)}
/>
<TouchableOpacity style={styles.submitBtn} title="Login" onPress={() => signIn()}>
<Text style={styles.appButtonText}>Login</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
formView: {
marginTop: 45,
display: "flex",
alignItems: "center",
},
input: {
marginTop: 20,
width: 300,
height: 40,
paddingHorizontal: 10,
borderRadius: 5,
backgroundColor: 'white',
},
submitBtn: {
backgroundColor: "#FFE17D",
color: "#E6646E",
fontWeight: "bold",
width: 150,
height: 40,
marginTop: 20,
borderColor: "#E6646E",
borderRadius: 5,
display: "flex",
justifyContent: "center",
borderWidth: 1,
},
appButtonText: {
fontSize: 18,
color: "#E6646E",
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase"
}
});
Only the stack screens have access to the props navigation. You can try sending navigation to LoginForm but that works only if Login is a Stack Screen.
const Login = ({navigation}) => {
return (
<View style={styles.mainWrapper}>
<Image style={styles.logo} title="Logo" source={require('../assets/box.png')}/>
<LoginForm navigation={navigation}/>
</View>
);
}
Or you can have a look in the useNavigation hook

Categories