Reputation: 2017
I have the following:
function HomeScreen({navigation}) {
const uid = firebase.auth().currentUser?.uid;
const [user, setUser] = useState({});
useEffect(() => {
const subscriber = firebase.firestore()
.collection('users')
.doc(uid)
.onSnapshot(documentSnapshot => {
setUser(documentSnapshot.data());
});
return () => subscriber();
}, [uid]);
return (
<Screen style={styles.screen}>
<View>
<Text>Hello</Text>
<Text style={styles.nameText}>{user.username}</Text>
<Text>hello</Text>
<View style={{paddingBottom:20, marginRight:200, paddingTop:40}}>
<DefaultButton
title="Edit your profile"
onPress={() => navigation.navigate("EditProfileScreen")}
color='#F9CDAD'
/>
</View>
</View>
</Screen>
)
}
I'm trying to display the username:
<Text style={styles.nameText}>{user.username}</Text>
But im getting the following error:
FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: undefined
When I log the uid
defined above const uid = firebase.auth().currentUser?.uid;
, it returns undefined
.
Upvotes: 0
Views: 68
Reputation: 598807
It looks like uid
isn't set yet by the time your userEffect
gets triggered.
To solve that, use an auth state listener to respond to auth state changes:
useEffect(() => {
let subscriber;
firebase.auth().onAuthStateChanged((user) => {
if (user && !subscriber) {
subscriber = firebase.firestore()
.collection('users')
.doc(user.uid)
.onSnapshot(documentSnapshot => {
setUser(documentSnapshot.data());
});
});
return () => subscriber();
}, [uid]);
You'll probably need to tweak that return
at the end, as the subscriber
is now set asynchronously.
Upvotes: 1
Reputation: 1921
The issue is that effectively, you are using an undefined
value from the reference uid
in your useEffect()
part.
You correctly have setted it as a dependency in your dependencies array, but you are missing to check if the value is actually defined, for it to be safe to use later.
useEffect(() => {
// this will run two times, first when 'uid' is initialized (as undefined) -> which will give your error
// and then, when it gets defined with actual value.
// --> fix: check 'uid' to be defined before using it.
if(!uid) {
// uid not defined yet, just return.
return
}
// uid is defined here, it's safe to use.
const subscriber = firebase.firestore()
.collection('users')
.doc(uid)
.onSnapshot(documentSnapshot => {
setUser(documentSnapshot.data());
});
return () => subscriber();
}, [uid]);
Upvotes: 1