React Native: Standalone, managed app on Android crashes when using Facebook login (works on iOS)

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 component:

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

I needed to add my appId to Facebook.initializeAsync()

const handleFacebook = async () => {

    try {
      await Facebook.initializeAsync("1111111111"); // <-- your appId

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

      if (type === "success") {
        const credential = firebase.auth.FacebookAuthProvider.credential(token);
        // handle Firebase login logic here
      }

    }
    catch (e) {
      console.log("e : ", e);
      Alert.alert("", e);
    }
  }
1 Like