0
votes

I have a React Native app I built using the Expo managed workflow. I am using Facebook login for my app along with Firebase authentication. My understanding is this can not be tested when running in the Expo app, and can only be used in a standalone app.

FB login is working fine in my iOS standalone app, however, in android, it crashes before the Facebook login screen even appears. My LandingPage loads, but as soon as I press the "Login With Facebook" button, it crashes.

Below is my app.json file and my login code. Per the instructions, I have also added the Facebook Key Hash to my project on the Facebook developer site. Can anyone help me understand what is wrong?

app.json:

{
  "expo": {
    "name": "Pick Up",
    "slug": "PickUp",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/ball-and-glove-5.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "notification": {
      "icon": "./assets/ball-and-glove-5.png",
      "color": "#fff",
      "androidMode": "default"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "userInterfaceStyle": "light",
      "config": {
        "googleMobileAdsAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx",
        "googleMapsApiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      },
      "bundleIdentifier": "com.myapp.name",
      "buildNumber": "1.0.0"
    },
    "userInterfaceStyle": "automatic",
    "android": {
      "useNextNotificationsApi": true,
      "userInterfaceStyle": "dark",
      "config": {
        "googleMobileAdsAppId": "ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx",
        "googleMaps": {
          "apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
      },
      "package": "com.myapp.name",
      "versionCode": 1
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "facebookScheme": "fbxxxxxxxxxxxxxxxx",
    "facebookAppId": "xxxxxxxxxxxxxxx",
    "facebookDisplayName": "myname"
  }
}


Login Code:


import React, { useState, useEffect, useContext } from 'react';
import { Alert, Animated, Image, StatusBar, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as WebBrowser from 'expo-web-browser';
import * as Facebook from 'expo-facebook';
import * as firebase from 'firebase';

import { loginUser } from '../../firebase.js';
import { StoreContext } from '../../contexts/storeContext';

const turquoise = "#4ECDC4";

const LandingPage = ({ navigation }) => {

  const store = useContext(StoreContext);

  const handleFacebook = async () => {

    try {
      await Facebook.initializeAsync();

      const options = {
        permissions: ["public_profile"]
      }
      const { type, token } = await Facebook.logInWithReadPermissionsAsync(options);

      if (type === "success") {
        const credential = firebase.auth.FacebookAuthProvider.credential(token);
        if (credential) {
          const bool = await loginUser(credential);
        }
      }

      else {
        Alert.alert("", "There was a problem. Please try again.");
      }
    }
    catch (e) {
      console.log("e : ", e);
      Alert.alert("", e);
    }
  }

  return (
    <View>
      <StatusBar barStyle="dark-content" backgroundColor={ turquoise } />

      <View>
        <TouchableOpacity onPress={ handleFacebook }>
          <Ionicons name="logo-facebook" />
          <Text>Continue with Facebookk</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={ () => navigation.navigate("PhoneVerification") }>
          <Text>Use cell phone number</Text>
        </TouchableOpacity>
      </View>
      <View>
        <Image
          resizeMode="contain"
          source={require('../../assets/new-logo.png')}
        />
      </View>
    </View>
  )
}
1

1 Answers

0
votes

The issue was that for Android, Facebook.initializeAsync() needs to be passed an argument -- your FB appID.

  const handleFacebook = async () => {

    try {
      await Facebook.initializeAsync("123456789"); // <-- your FB appID

      const options = {
        permissions: ["public_profile"]
      }
      const { type, token } = await Facebook.logInWithReadPermissionsAsync(options);

      if (type === "success") {
        const credential = firebase.auth.FacebookAuthProvider.credential(token);
        
        // do the rest of your Firebase login logic
      }

      else {
        Alert.alert("", "There was a problem. Please try again.");
      }
    }
    catch (e) {
      console.log("e : ", e);
      Alert.alert("", e);
    }
  }