开发者问题收集

React native - 函数 CollectionReference.doc() 需要其第一个参数

2021-02-23
67

我有以下内容:

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>
)
}

我正在尝试显示用户名:

<Text style={styles.nameText}>{user.username}</Text>

但是我收到以下错误:

FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: undefined

当我记录上面定义的 uid const uid = firebase.auth().currentUser?.uid; 时,它返回 undefined

2个回答

在您的 userEffect 被触发时,似乎 uid 尚未设置。

要解决该问题,请 使用身份验证状态监听器 来响应身份验证状态更改:

  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]);

您可能需要在最后调整 return ,因为 subscriber 现在是异步设置的。

Frank van Puffelen
2021-02-23

问题在于,实际上,您在 useEffect() 部分中使用了来自引用 uidundefined 值。

您已正确地将其设置为依赖项数组中的依赖项,但您缺少检查该值是否实际定义,以便以后可以安全使用。

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]);
tmilar
2021-02-23