Host Android Sign in with Apple function on firebase

Host your server for sign in with apple using Android on Firebase

Fri, 26 Jan 2024

Apple is on my shit list for making sign in with apple much harder to integrate into Android compared to iOS. In order to get this done you need a separate server to process the requests. I’m not going to go into details on certificates, tokens and other things you may need. I will just be giving you the code

Create a new firebase function and add this to the index.js

import * as functions from "firebase-functions";
import {logger} from "firebase-functions";
const firebaseAdmin = require('firebase-admin');

const express = require("express");
const bodyParser = require("body-parser");

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));

const redirectUrl = function(body: any, ANDROID_PACKAGE_IDENTIFIER: string): string {
    return `intent://callback?${new URLSearchParams(
        body
    ).toString()}#Intent;package=${
        ANDROID_PACKAGE_IDENTIFIER
    };scheme=signinwithapple;end`;
}

// The callback route used for Android, which will send the callback parameters from Apple into the Android app.
// This is done using a deeplink, which will cause the Chrome Custom Tab to be dismissed and providing the parameters from Apple back to the app.
app.post("/callbacks/sign-in-with-apple",  (request: any, response: any) => {
    const ANDROID_PACKAGE_IDENTIFIER = "com.your.indentifier";
    const redirect = redirectUrl(request.body, ANDROID_PACKAGE_IDENTIFIER);

    logger.info(`Redirecting to ${redirect}`);

    response.redirect(307, redirect);
});

exports.auth = functions.https.onRequest(app);

exports.app = app;

Do a firebase deploy to deploy your new function. Finally use it in your app. If you have sign in with apple for flutter you just need to add this section

      final appleCredential = await SignInWithApple.getAppleIDCredential(
        scopes: [
          AppleIDAuthorizationScopes.email,
          AppleIDAuthorizationScopes.fullName
        ],
        # This section below is for android.  clientId should match identifier made in apple console
        webAuthenticationOptions: WebAuthenticationOptions(
            clientId: "com.your.identifier.service",
            redirectUri: Uri.parse(appleRedirectUri)),
        nonce: nonce,
      );

Bonus - Testing

If you’re interested in doing offline tests this is what they would look like

const test = require('firebase-functions-test')({
   authDomain: "",
   projectId: "",
   storageBucket: "",
   messagingSenderId: ""
}, process.env.GOOGLE_APPLICATION_CREDENTIALS);

const supertest = require("supertest");
const {createServer} = require("http");

describe('Authentication', function () {
   let functionsToTest, request;

   // adds the functions to test
   before(function () {
       functionsToTest = require('../lib/index');
       request = supertest(createServer(functionsToTest.app));
   });
   // cleans up firebase after each test
   after(function () {
       test.cleanup();
   });

   describe('Sign in with apple on Android', function () {
       it('should return redirect to URI', function (done) {
           request.post('/callbacks/sign-in-with-apple')
               .send({domain: "test"})
               .set('Accept', 'application/json')
               .expect(307)
               .expect('Location', "intent://callback?#Intent;package=com.your.identifier;scheme=signinwithapple;end")
               .end(function(err) {
                   if (err) return done(err);
                   return done();
               });
       });
   });
});
Buy Me A CoffeeDigitalOcean Referral Badge
Loading...
Edward Beazer

Edward Beazer - I just like to build shit. Sometimes I get stuck for hours, even days while trying to figure out how to solve an issue or implement a new feature. Hope my tips and tutorials can save you some time.

DigitalOcean Referral Badge