javascript 为什么我的firebase onAuthStateChanged()触发多次?(React Native)

o0lyfsai  于 2023-05-16  发布在  Java
关注(0)|答案(2)|浏览(128)

当我根据console.log使用firebase-authentication登录和退出时,我的firebase方法onAuthStateChanged()触发了几次。它不是应该只在登录和注销时触发一次吗?结果是,当注销时,导航到上一页会被触发多次。代码如下:

componentDidMount() {
    fbAuth.onAuthStateChanged(user => this.loginFunc(user));
}

loginFunc(user) {
   if (user) {
     console.log('LOGGED IN');
}else {
  console.log('LOGGED OUT');
  this.props.navigation.navigate('FbLogin');
}
console.log('onAUTH LOGGED IN: ', user);
}

这就是控制台的样子。正如您所看到的,登录和注销都是在单击注销时触发的。登录时,它会触发两次....

LOGGED OUT
FbLogin.js:46 onAUTH:  null
LoggedIn.js:27 LOGGED OUT
LoggedIn.js:30 onAUTH LOGGED IN:  null
FbLogin.js:44 LOGGED OUT
FbLogin.js:46 onAUTH:  null

我的Logout按钮看起来像这样:

<TouchableHighlight //LOGOUT
   style={{
      ...
   }}
   onPress={() => {
      fbAuth.signOut();
      this.setState({ loginState: "You are logged out" });
   }}
   >
      <Text>Logout</Text>
   </TouchableHighlight>
flvlnr44

flvlnr441#

是的,这是正常的,onAuthStateChanged将继续触发,我通过使用以下代码解决了这个问题:

var authFlag = true;
  Firebase.onAuthStateChanged( user => {
    if(authFlag) {
      authFlag = false;
      if (user) {
        // Do something,
      }
      else {
        // Alert.alert("Auth Error")
      }
    }
  });
jecbmhm3

jecbmhm32#

我能够通过在onAuthStateChanged侦听器中解析promise来解决这个问题。在我的例子中,我只对用户的ID令牌感兴趣。

const [request, response, promptAsync] = Google.useAuthRequest({
      androidClientId: "XXXXXXX",
      iosClientId: "XXXXXXX",
      expoClientId: "XXXXXXX",
  });

  const promptGoogleLogin = useCallback(() => {
    promptAsync().catch(console.error);
  }, [promptAsync]);

  const loginWithFirebaseIdToken = async (idToken: string) => {
    // Send idToken to the backend to authenticate user and return custom token
  };

  useEffect(() => {
    const handleResponse = async (response: AuthSessionResult) => {
        if (response.type === "success") {
            const { authentication } = response;

            const credential = GoogleAuthProvider.credential(
              authentication.idToken,
              authentication.accessToken
            );

            await signInWithCredential(firebaseAuth, credential);

            const idToken = await getUserIdToken();

            // Send Firebase token to my backend to continue auth flow
            loginWithFirebaseIdToken(idToken);
        }
    }

    if (response) {
        handleResponse(response);
    }
  }, [response]);

  // The secret ingredient
  const getUserIdToken = (): Promise<string> => {
    return new Promise((resolve) => {
      firebaseAuth.onAuthStateChanged((user) => {
        if (user) {
          user.getIdToken().then(resolve);
        }
      });
    });
  };

相关问题