首页 > 解决方案 > 来自带有 Facebook Auth 和 React Native 的 Firebase 的“回调 URL 不包含状态”错误

问题描述

我正在尝试使用 Firebase 和 Facebook Auth 编写一个 React Native 应用程序。这是完整的应用程序代码:

import React from 'react';
import { StyleSheet, View } from 'react-native';

import { LoginManager, AccessToken, LoginButton } from 'react-native-fbsdk';

import * as f from './config/firebase';

export default class App extends React.Component {
  fbLoginHandler(error, result) {
    if (error) {
      alert('Login failed with error: ' + error);
    } else if (result && result.isCancelled) {
      alert('Login cancelled');
    } else {
      AccessToken.getCurrentAccessToken().then((accessTokenData) => {
        const credential = f.provider.credential(accessTokenData.accessToken);
        f.auth.signInAndRetrieveDataWithCredential(credential).then((s) => {
          alert('Success! ' + s);
        }, (signinError) => {
          console.log('Signin error', signinError);
          alert('Signin error' + signinError);
        });
      }, (tokenError) => {
        alert('Some error occurred' + tokenError);
      });
    }
  }

  render () {
    return (
      <View style={styles.container}>
        <LoginButton
          readPermissions={['public_profile', 'email']}
          onLoginFinished={(error, result) => this.fbLoginHandler(error, result)}
          onLogoutFinished={() => alert('logout.')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF'
  }
});

这是我的 Firebase 配置文件('./config/firebase'上述代码段中的导入):

import * as firebase from 'firebase';

const config = {
  apiKey: <api key>,
  authDomain: <auth domain>,
  databaseURL: <database URL>,
  projectId: <project ID>,
  storageBucket: <storage bucket>,
  messagingSenderId: <messaging sender ID>
};

firebase.initializeApp(config);

export const database = firebase.database();
export const auth = firebase.auth();
export const provider = new firebase.auth.FacebookAuthProvider();

我已按照 Firebase 文档中的说明在我的 Facebook 控制台上输入了所需的 OAuth 重定向 URI。我还根据其他 Stack Overflow 线程中的建议添加了一些其他内容。我授权的重定向 URI 是:

https://<MyAppID>.firebaseapp.com/__/auth/handler
https://auth.firebase.com/auth/facebook/callback
https://auth.firebase.com/v2/<MyAppID>/auth/facebook/callback
https://localhost/
http://localhost/

auth 进程获得了其中的一部分(我可以在我的 Facebook 控制台上看到用户已通过身份验证)但signInAndRetrieveDataWithCredential(credential)返回错误:

{
  code: "auth/internal-error",
  message: {
    error:{
      code:400,
      message:"Callback URL does not contain state: http://localhost?id_token=<token>&providerId=facebook.com",
      errors:[{
        message:"Callback URL does not contain state: http://localhost?id_token=<token>&providerId=facebook.com",
        domain:"global",
        reason:"invalid"
      }]
    }}
  }
}

我已经搜索了互联网、Facebook 开发人员文档、Firebase 文档,当然还有 Stack Overflow,但是我在任何地方都找不到对这个特定错误的任何引用。我相信这个错误——尽管是从 Firebase 函数返回的——只是从 Facebook Auth API 传递过来的,但我什至不能 100% 确定这一点。

我的假设是我必须在 Facebook 或 Firebase 中有一个不正确的配置设置,但我已经尝试更改明显的设置(例如重定向 URI、所有 OAuth 选项切换等),而错误消息没有变化。

任何见解将不胜感激!

标签: firebasereact-nativefirebase-authenticationfacebook-authentication

解决方案


虽然我仍然无法诊断出这个特定的错误,但我找到了一个有效的解决方案,即使用第三方react-native-firebase包代替谷歌的firebase包:

import React from 'react';
import { StyleSheet, View } from 'react-native';

import { LoginManager, AccessToken, LoginButton } from 'react-native-fbsdk';

import firebase from 'react-native-firebase';

export default class App extends React.Component {
  fbLoginHandler(error, result) {
    if (error) {
      alert('Login failed with error: ' + error);
    } else if (result && result.isCancelled) {
      alert('Login cancelled');
    } else {
      AccessToken.getCurrentAccessToken().then((accessTokenData) => {
        const credential = firebase.auth.FacebookAuthProvider.credential(accessTokenData.accessToken);
        firebase.auth().signInAndRetrieveDataWithCredential(credential).then((s) => {
          alert('Success! ' + s);
        }, (signinError) => {
          console.log('Signin error', signinError);
          alert('Signin error' + signinError);
        });
      }, (tokenError) => {
        alert('Some error occurred' + tokenError);
      });
    }
  }

  render () {
    return (
      <View style={styles.container}>
        <LoginButton
          readPermissions={['public_profile', 'email']}
          onLoginFinished={(error, result) => this.fbLoginHandler(error, result)}
          onLogoutFinished={() => alert('logout.')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF'
  }
});


推荐阅读