Gurmukh Singh
Gurmukh Singh

Reputation: 2017

React native - Function CollectionReference.doc() requires its first argument

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

Answers (2)

Frank van Puffelen
Frank van Puffelen

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

tmilar
tmilar

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

Related Questions