Firebase Facebook的身份验证失败

时间:2018-12-05 18:17:48

标签: facebook firebase react-native expo

我有一个屏幕,正在尝试使用Firebase的Facebook身份验证。

使用博览会,我可以成功生成facebook令牌。接下来,我要做的就是使用此令牌生成证书,我认为这也成功运行了,但是当我尝试使用凭据登录到Firebase时,我得到错误登录失败。 我不确定是什么问题。在让他们使用facebook auth登录之前,我需要使用电子邮件和密码注册用户吗?

任何帮助将不胜感激...

这是代码...

import React from 'react';
import {
  ActivityIndicator,
  AsyncStorage,
  Button,
  StatusBar,
  StyleSheet,
  View,
  Text,
} from 'react-native';

import Expo, { Facebook } from 'expo';
import * as firebase from 'firebase';

import ModalActivityIndicator from '../../components/ModalActivityIndicator';
export default class SignInFacebookScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false,
    };
  }
  componentDidMount = async () => {
    await this.facebookLogin();
  };
  facebookLogin = async () => {
    const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync(
      '<AppId>',
      {
        permissions: ['public_profile', 'email'],
      }
    );

    if (type === 'success') {
      await this.callGraph(token);
    } else if (type === 'cancel') {
      alert('Cancelled!', 'Login was cancelled!');
    } else {
      alert('Oops!', 'Login failed!');
    }
  };
  callGraph = async token => {
    const response = await fetch(
      `https://graph.facebook.com/me?access_token=${token}`
    );
    const userProfile = JSON.stringify(await response.json());
    const credential = firebase.auth.FacebookAuthProvider.credential(token);
    await this.firebaseLogin(credential);
  };
  // Sign in with credential from the Facebook user.
  firebaseLogin = async credential => {
    firebase
      .auth()
      .signInAndRetrieveDataWithCredential(credential)
      .then(() => {
        this.setState({
          isLoading: false,
          hasError: false,
          errorMessage: null,
        });
        this.props.navigation.navigate('App');
      })
      .catch(error => {
        this.setState({
          isLoading: false,
          hasError: true,
          errorMessage: error.errorMessage,
        });
      });
  };

  render() {
    let { isLoading, hasError, errorMessage } = this.state;
    return (
      <View style={styles.container}>
        <ModalActivityIndicator isLoading={!!isLoading} />
        <Text>Sign In with Facebook</Text>
        {hasError && (
          <React.Fragment>
            <Text style={[styles.errorMessage, { color: 'black' }]}>
              Error logging in. Please try again.
            </Text>
            <Text style={[styles.errorMessage, { color: 'black' }]}>
              {errorMessage}
            </Text>
          </React.Fragment>
        )}
      </View>
    );
  }
}

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

1 个答案:

答案 0 :(得分:0)

我用以下代码解决了这个问题。似乎问题出在改变异步功能。

import React from 'react';
import {
  ActivityIndicator,
  AsyncStorage,
  Button,
  StatusBar,
  StyleSheet,
  View,
  Text,
} from 'react-native';

import Expo, { Facebook } from 'expo';
import * as firebase from 'firebase';

import ModalActivityIndicator from '../../components/ModalActivityIndicator';

export default class SignInFacebookScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false,
      firstName: '',
      lastName: '',
    };
  }
  componentDidMount = async () => {
    const fbToken = await this.getFacebookToken();
    const userProfile = await this.getFacebookUserProfile(fbToken);
    this.setUserDetails(userProfile);
    const credential = await this.getFirebaseFacebookCredential(fbToken);
    await this.loginToFirebaseWithFacebook(credential);
  };

  getFacebookToken = async () => {
    const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync(
      '<AppId>',
      {
        permissions: ['public_profile', 'email'],
      }
    );
    if (type === 'success') {
      return token;
    } else if (type === 'cancel') {
      alert('Cancelled!', 'Login was cancelled!');
    } else {
      alert('Oops!', 'Login failed!');
    }
  };

  getFacebookUserProfile = async token => {
    this.setState({ isLoading: true });
    const response = await fetch(
      `https://graph.facebook.com/me?access_token=${token}&fields=first_name,last_name`
    );
    const userProfile = JSON.stringify(await response.json());
    return userProfile;
  };

  setUserDetails = userProfile => {
    const userProfileObj = JSON.parse(userProfile);
    this.setState({
      firstName: userProfileObj.first_name,
      lastName: userProfileObj.last_name,
    });
  };

  getFirebaseFacebookCredential = async token => {
    const credential = firebase.auth.FacebookAuthProvider.credential(token);
    return credential;
  };

  loginToFirebaseWithFacebook = async credential => {
    firebase
      .auth()
      .signInAndRetrieveDataWithCredential(credential)
      .then(() => {
        let user = firebase.auth().currentUser;
        firebase
          .database()
          .ref('users/' + user.uid)
          .update({
            firstName: this.state.firstName,
            lastName: this.state.lastName,
          });
      })
      .then(() => {
        this.setState({
          isLoading: false,
          haserror: false,
          errorMessage: null,
        });
        this.props.navigation.navigate('App');
      });
  };

  render() {
    let { isLoading, hasError, errorMessage } = this.state;
    return (
      <View style={styles.container}>
        <ModalActivityIndicator isLoading={!!isLoading} />
        <Text>Sign In with Facebook</Text>
        {hasError && (
          <React.Fragment>
            <Text style={[styles.errorMessage, { color: 'black' }]}>
              Error logging in. Please try again.
            </Text>
            <Text style={[styles.errorMessage, { color: 'black' }]}>
              {errorMessage}
            </Text>
          </React.Fragment>
        )}
      </View>
    );
  }
}

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