Mega Bundle SALE is ON! Get ALL of our amazing React Native codebases with 85% OFF discount ūüĒ•

Once Apple introduced the Login with Apple button, they also updated their App Store rules, that any app that supports Facebook Login and Google Login, must implement the Apple Sign-in variant too. Otherwise, the app would simply be rejected during the App Review process. So let’s see what it takes to implement Apple Login in React Native, with Firebase Auth.

In this tutorial we will show you how to integrate Apple Sign-in in your React Native application. We will cover everything you need to know to add this feature to your app, including the full source code. We are going to assume you already have some level of familiarity with React Native and Firebase.

We are also going to assume the Firebase config file is already integrated into your app, as this tutorial only covers the Sign-in with Apple part.

1. Enable Apple Sign-in on Your Firebase Dashboard

You have to enable Apple Sign-in on your Firebase dashboard under Firebase Auth -> Settings -> Sign-in Methods tab.

2. Install The Required Dependencies into React Native

To follow this article you have to install the following 2 important React Native Firebase dependencies that we will need using the following command. Please check your package.json file first, since it’s highly likely that you already have these packages installed, if you were already using Firebase into your codebase. If they are not there, simply run:

yarn add @react-native-firebase/app && @react-native-firebase/auth

The Firebase Authentication dependency @react-native-firebase/auth is the dependency that registers ( or signs in) users in your database.

The Firebase Auth package handles the Apple authentication process on the Firebase side and requires two variables: identityToken and nonce. To get these variable we will need a third dependency: @invertase/react-native-apple-authentication.

yarn add @invertase/react-native-apple-authentication
3. Getting Apple Sign-in Credentials

First step is to retrieve identityToken and nonce. We will call this method when the Apple Sign-in button gets pressed (see next steps).

// api.js
import appleAuth, { AppleAuthRequestScope, AppleAuthRequestOperation, } from '@invertase/react-native-apple-authentication' export const onAppleSignin = () => { return new Promise(async (resolve, _reject) => { try { const appleAuthRequestResponse = await appleAuth.performRequest({ requestedOperation: AppleAuthRequestOperation.LOGIN, requestedScopes: [ AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME, ], }) const { identityToken, nonce } = appleAuthRequestResponse loginWithApple(identityToken, nonce) .then(async response => { if (response?.user) { //handle successful login resolve({success: true}) } else { //handle unsuccessful login resolve({success: false}) } }) } catch (error) { console.log(error) resolve({success: false}) } }) }

Then we sign the user in using the loginWithApple function coded below:

// api.js

const loginWithApple = (identityToken, nonce) => { 
  const appleCredential = RNFirebaseAuth.auth.AppleAuthProvider.credential(
    identityToken,
    nonce,
  )

  return new Promise((resolve, _reject) => {
    RNFirebaseAuth
      .auth()
      .signInWithCredential(credential)
      .then(response => {
        const isNewUser = response.additionalUserInfo.isNewUser
        const {
          first_name,
          last_name,
          family_name,
          given_name,
        } = response.additionalUserInfo.profile
        const { uid, email, phoneNumber, photoURL } = response.user
        const defaultProfilePhotoURL =
          'https://www.iosapptemplates.com/wp-content/uploads/2019/06/empty-avatar.jpg'

        if (isNewUser) {
          const timestamp = firebase.firestore.FieldValue.serverTimestamp()
          const userData = {
            id: uid,
            email: email || '',
            firstName: first_name || given_name || '',
            lastName: last_name || family_name || '',
            phone: phoneNumber || '',
            profilePictureURL: photoURL || defaultProfilePhotoURL,
            userID: uid,
            createdAt: timestamp,
          }
          // PERSIST NEW USER DATA TO YOU PREFFERRED DB AND SAVE ON REDUX
        }
        // UPDATE USER LAST LOGIN
        resolve({success: true})
        
      })
      .catch(_error => {
        console.log(_error)
        resolve({ success: false })
      })
  })
}
4. Display The Apple Sign-In Button
// App.js
import React from 'react'; import { AppleButton, } from '@invertase/react-native-apple-authentication' import {onAppleLogin} from './api' function LoginScreen(){ return ( <AppleButton cornerRadius={25} buttonType={AppleButton.Type.SIGN_IN} onPress={onAppleLogin} /> ) }
5. Exclude Incompatible Devices and Platforms

As we already know, Apple Sign-In is not supported on all devices, such as Android devices. So we have to add some validation logic to check whether it is supported on the current device. A possible approach would be to check if the user is making use of an iOS device:

return (
  <>
    {Platform.OS === 'ios'?
      <AppleButton
        cornerRadius={25}
        buttonType={AppleButton.Type.SIGN_IN}
        onPress={onAppleLogin}
      />:
      <Text>Apple Sign-In is not supported on this device</Text>
    }
  </>
)

The above approach is okay but it does not cover certain use cases. For example a user using a MacOS version of your app or a the Web version on an iOS or MacOS device. To resolve this we can use a function provided by @invertase/react-native-apple-authentication:

// App.js
import React from 'react'; import appleAuth, { AppleButton, } from '@invertase/react-native-apple-authentication' import {onAppleLogin} from './api' function LoginScreen(){ return ( {appleAuth.isSupported ? <AppleButton cornerRadius={25} buttonType={AppleButton.Type.SIGN_IN} onPress={onAppleLogin} />: <Text>Apple Sign-In is not supported on this device</Text>
) }
Conclusion

In this article we put together a very basic React Native app to showcase how Apple Sign-in works when integrated with Firebase Auth. Create your own app, and use our implementation to play around with the code.

As an exercise, you could try to handle the error messages, or go one step further, and implement the persistent credentials feature, which is a must in any onboarding experience.

If you made it to the end of this article you should be able to integrate Apple Sign-In into any React Native app seamlessly, for both new and existing projects.

Categories: React Native

Leave a Reply

Your email address will not be published. Required fields are marked *

Shopping Cart