Sign In with Apple + Expo React Native + Firebase + Mac m1

Written by herschelle | Published 2023/01/20
Tech Story Tags: ios-app-development | expo | apple-m1 | react-native | tutorial | programming | coding | apple

TLDRIn order to create Login with Google and Apple on your expo app with firebase, you need to understand few things. You cannot create login with Apple without exporting the expo. app into a native app bundle. You will need an Apple computer, MacBook Air or a Mac Desktop with Xcode installed and an Apple Developer’s Account.via the TL;DR App

In order to create Login with Google and Apple on your expo app with firebase, you need to understand few things:

  1. You cannot create login with Apple without exporting the expo app into a native app bundle. So you need to understand that, although I will explain how to do that in the article below.
  2. When you create a project on firebase, you will need to create .plist file for apple sign in
  3. You will need an Apple computer. A MacBook, MacBook Air or a Mac Desktop with Xcode installed.
  4. You will need Apple Developer’s Account which usually cost $99 a year.
  5. You have basic understanding of React Native and CLI.

OK, so now you can proceed. Let’s first install the dependencies.

Step 1# Create an Expo App

It’s really easy to create an expo app.

Just open your VS Code or any of your favourite code editor and run the commands below:

yarn create expo-app

yes, I am a fan of yarn 😀

Now you have a blank expo React Native app.

But as we have learned above, we cannot implement Sign in with Apple, without exporting this app.

Why now?

Because sign in with apple is a native feature. Just like “In-app purchase” and many others.

And to implement native features, you have to export expo app into a bare app and then do the configuration.

Now you can simply run this command and open your expo app in a simulator

expo start

Step 2# Export Expo App to Bare iOS

In order to export your expo managed app into a bare iOS app, you just have to run this command.

expo run:ios

This will create an /ios folder and install CocoaPods into it.

As you can see in the screenshot below that, after the export is finished, you have an iOS folder as well as a new app on your simulator.

This proves that you successfully exported the app.

Step 3# Install rn firebase package

After that, you simply go to https://rnfirebase.io/

This is a very handy package created to make React Native developer’s life easier when it comes to integrate firebase into your app.

Just run the following command:

yarn add @react-native-firebase/app

Yes, I am still a yarn fan 😀

This should install rnfirebse app package within minutes.

Step 4# iOS setup for firebase

To allow the iOS app to securely connect to your Firebase project, a configuration file must be downloaded and added to your project, and you must enable frameworks in CocoaPods.

Login into your firebase account and create a firebase project. (I am not going to tell you how to do that because it’s very simple).

Then click on add a new iOS application and enter your project’s details.

The "iOS bundle ID" must match your local project bundle ID. I would suggest to use a reverse domain to have a unique id.

Something like com.YOUR-DOMAIN.ios

Once done, download the .plist file GoogleService-Info.plist file.

After this, you need to enable Sign in with apple in your:

Step 5# Configure your Xcode settings

Using Xcode, open the projects /ios/{projectName}.xcodeproj file (or /ios/{projectName}.xcworkspace if using Pods). Because we exported our app via expo and installed pods.

We will use .xcworkspace

After that, just update the bundle identifier:

Right-click on the project name and "Add files" to the project, as shown above:

Locate the file we downloaded in step 4 and select it.

Tip: Make sure you select copy in needed checkbox as this will copy your google plist file into your project.

Then click on the run project button and see if your app is running on a simulator.

Firebase needs to use the credentials on iOS, that is why the Firebase iOS SDK must be configured.

To do this, open your /ios/{projectName}/AppDelegate.mm file (or AppDelegate.m if on older react-native), and add the following:

At the top of the file, import the Firebase SDK:

#import <Firebase.h>

Within your existing didFinishLaunchingWithOptions method, add the following to the top of the method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Add me --- \/
  [FIRApp configure];
  // Add me --- /\
  // ...
}


Step 6# Link firebase library

React Native Firebase library must be linked to your project in order to implement this feature.

But because we are using React Native 0.60+ we automatically have access to "autolinking", hence require no further manual installation steps.

To automatically link the package, we just have to rebuild our project. To do that, just cd into your /ios folder first

# iOS apps

cd ios/

pod install --repo-update

But if you are on m1 MacBook then it will throw errors. To overcome that you just use following commands

sudo arch -x86_64 gem install ffi

// then

arch -x86_64 pod install

// tip in order to remove the pod.lock file and install fresh use

arch -x86_64 pod install --repo-update

If this worked, drop a ❤️ in the comments 🙃

If you get an error:

[!] The following Swift pods cannot yet be integrated as static libraries:

The Swift pod `FirebaseCoreInternal` depends upon `GoogleUtilities`, 
which does not define modules. To opt into those targets generating module maps 
(which is necessary to import them from Swift when building as static libraries), 
you may set `use_modular_headers!` globally in your Podfile, 
or specify `:modular_headers => true` for particular dependencies.


Then please add as show below in your pod file. This answer is foundhere.

// after
  flags = get_default_flags()

  pod 'GoogleUtilities', :modular_headers => true 

// before
  use_react_native!(

After this, build your project on Xcode and see if it succeeded.

If yes, you are ready to move forward.

Step 7# Enable Apple Sign-in Capability

Now this step consist of two parts.

  1. Where you have to log in into your developer account and enable the sign in with apple capability
  2. You have to select sign in with apple capability from your Xcode

So let’s start with the first.

Login into your Apple developer account and navigate to certificates.

Then click on + button and add identity.

After that, provide the description for your app and the bundle identifier.

Scroll down and select sign-in with Apple

Then click continue and register.

After that the secont part starts, where you just need to open your Xcode and click on your application bundle.

Select signing & capabilities

Click on + capability button and search for apple.

Then select Sign in with Apple

After you select this option, you should see it added into the app like below:

Step 8# Create Sign in function to handle user request.

Now this is time we all were waiting for.

Import the following packages into your login screen or app.js file where ever you are implementing the sign in with apple feature.

import auth from '@react-native-firebase/auth';
import { appleAuth } from '@invertase/react-native-apple-authentication';

I think I myself forgot about installing the @react-native-firebase/auth

If you did to then please install it and then re-install the pods inside your /ios folder.

Create a login function in the same file as described below:

async function onAppleButtonPress() {
  // Start the sign-in request
  const appleAuthRequestResponse = await appleAuth.performRequest({
    requestedOperation: appleAuth.Operation.LOGIN,
    requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
  });

  // Ensure Apple returned a user identityToken
  if (!appleAuthRequestResponse.identityToken) {
    throw new Error('Apple Sign-In failed - no identify token returned');
  }

  // Create a Firebase credential from the response
  const { identityToken, nonce } = appleAuthRequestResponse;
  const appleCredential = auth.AppleAuthProvider.credential(identityToken, nonce);

  // Sign the user in with the credential
  return auth().signInWithCredential(appleCredential);
}

Now, let’s create a button to trigger this function. For that first import apple Button:

import { appleAuth, AppleButton } from '@invertase/react-native-apple-authentication';

Then create a button:

function AppleSignIn() {
  return (
    <AppleButton
      buttonStyle={AppleButton.Style.WHITE}
      buttonType={AppleButton.Type.SIGN_IN}
      style={{
        width: 160,
        height: 45,
      }}
      onPress={() => onAppleButtonPress().then(() => console.log('Apple sign-in complete!'))}
    />
  );
}

Perfect, now you can test the button functionality by running the app on your simulator.

Step 9# Run the code on simulator for final test.

And once you are logged in with your Apple ID.

Tip: in order to login into your Apple account via simulator, you need to first log in into your iCloud and then accept some terms and conditions.

You can check it into your firebase project if you can see the user entry:

If you like this article, let me know in your comments. Peace!


Written by herschelle | Saas Founder | Growth Hacker | Mentor
Published by HackerNoon on 2023/01/20