- Published on
Configure Firebase Auth with Apple Login in an Expo App (2025 Guide)
- Authors
- Name
- Ahmed Farid
- @
CAUTION
Apple requires “Sign in with Apple” if you offer other social logins. Follow the checklist to stay compliant and avoid App Store rejections.
This tutorial shows how to power Sign in with Apple using Firebase Auth inside an Expo SDK 50 project. We will:
- Register identifiers and keys in Apple Developer portal.
- Enable Apple provider in Firebase console.
- Implement the login flow with
expo-apple-authentication
and@react-native-firebase/auth
(or web SDK v10). - Handle first-time name / email, account linking, and token refresh.
Table of Contents
- Table of Contents
- 1. Prerequisites & Terminology
- 2. Create Identifiers & Keys in Apple Developer
- 3. Enable Apple Provider in Firebase
- 4. Install Dependencies in Expo Project
- 5. Initialise Firebase SDK
- 6. Implement Sign in with Apple Flow
- 7. Handling Account Linking with Email/Password
- 8. Supporting Expo Web (Optional)
- 9. Testing & Deployment
- 10. Troubleshooting
- 11. Security & Compliance Checklist
- 12. Further Reading & Resources
- 13. Conclusion
1. Prerequisites & Terminology
- Expo SDK 50 (managed or bare).
- macOS with Xcode 15.
- Firebase project already created.
Term | Meaning |
---|---|
Service ID | Apple OAuth client identifier used by Firebase │ |
Key ID | Identifier for the .p8 private key │ |
Client Secret | JWT signed with the private key—Firebase generates automatically │ |
2. Create Identifiers & Keys in Apple Developer
- Certificates, IDs & Profiles → Identifiers: Create an App ID (e.g.
com.yourco.applefirebase
). Enable Sign in with Apple capability. - Keys → +: New key → enable Sign in with Apple, link to App ID, download
.p8
. Note Key ID. - Identifiers → Services IDs: New service ID
com.yourco.applefirebase.service
. Under Web Auth config add redirect URL:https://YOUR_FIREBASE_PROJECT.firebaseapp.com/__/auth/handler
.
3. Enable Apple Provider in Firebase
Firebase Console → Authentication / Sign-in method → Apple → Enable.
Enter:
- Services ID from step 3.
- Apple Team ID.
- Key ID.
- Upload
.p8
. - Leave redirect default (
https://.../__/auth/handler
).
Firebase creates the client secret JWT and rotates automatically.
4. Install Dependencies in Expo Project
yarn add expo-apple-authentication @react-native-firebase/app @react-native-firebase/auth
# Or web SDK if you target Expo Web
yarn add firebase@10
Add Apple entitlement via app.json
:
{
"expo": {
"ios": {
"bundleIdentifier": "com.yourco.applefirebase",
"usesAppleSignIn": true,
},
},
}
Run npx expo prebuild --platform ios
to regenerate native project.
5. Initialise Firebase SDK
// src/lib/firebase.ts
import { initializeApp } from '@react-native-firebase/app'
import auth from '@react-native-firebase/auth'
const firebaseConfig = {
apiKey: '...',
authDomain: 'YOUR_PROJECT.firebaseapp.com',
projectId: 'YOUR_PROJECT',
appId: '1:123456:web:abcdef',
}
export const app = initializeApp(firebaseConfig)
export { auth }
6. Implement Sign in with Apple Flow
import * as Apple from 'expo-apple-authentication'
import { AppleAuthRequestResponse } from 'expo-apple-authentication'
import { auth } from '@/lib/firebase'
import { OAuthProvider, signInWithCredential } from '@react-native-firebase/auth'
async function appleLogin() {
const appleResponse: AppleAuthRequestResponse = await Apple.signInAsync({
requestedScopes: [
Apple.AppleAuthenticationScope.FULL_NAME,
Apple.AppleAuthenticationScope.EMAIL,
],
})
if (!appleResponse.identityToken) throw new Error('Apple Sign-in failed – no identity token')
// 1. Create Firebase credential
const provider = new OAuthProvider('apple.com')
const credential = provider.credential({
idToken: appleResponse.identityToken,
rawNonce: appleResponse.nonce, // Expo returns a secure nonce automatically
})
// 2. Sign in / link
const result = await signInWithCredential(auth(), credential)
// 3. Update display name on first login
if (appleResponse.fullName?.givenName && result.additionalUserInfo?.isNewUser) {
await result.user.updateProfile({
displayName: `${appleResponse.fullName.givenName} ${appleResponse.fullName.familyName}`,
})
}
}
Notes:
rawNonce
is required by Firebase to mitigate replay attacks.- Firebase handles token refresh and stores in device secure storage.
7. Handling Account Linking with Email/Password
If user previously created a password account with the same email:
try {
await signInWithCredential(auth(), credential)
} catch (err: any) {
if (err.code === 'auth/account-exists-with-different-credential') {
const methods = await auth().fetchSignInMethodsForEmail(err.email)
// prompt user to log in with method[0] then linkWithCredential
}
}
8. Supporting Expo Web (Optional)
On web, use Firebase signInWithPopup(new OAuthProvider('apple.com'))
. Apple restricts popup to Safari 14+. Consider fallback to Redirect flow.
9. Testing & Deployment
- Simulator with signed-in Apple ID supports Sign in with Apple.
- Test invalid credential by revoking key in Apple portal → expect Firebase 400.
- App Store listing: add Sign in with Apple demo video and privacy text.
10. Troubleshooting
Error | Fix |
---|---|
invalid_client / code 400 | Services ID mismatch between Firebase & Apple |
auth/missing-nonce | Pass rawNonce from Expo response |
identityToken null | User cancelled or iCloud not logged in |
11. Security & Compliance Checklist
✅ usesAppleSignIn: true
in app.json
.
✅ Provide Continue with Apple button equal prominence.
✅ Implement account deletion as per §5.1.1 App Store Review.
✅ Hide email if Apple returns email === null
.
12. Further Reading & Resources
- Firebase docs: Apple provider.
- Expo
expo-apple-authentication
docs. - Apple WWDC 2024: What’s new in Sign in with Apple.
13. Conclusion
You now have secure Sign in with Apple integrated with Firebase Auth in your Expo app—compliant, token-safe, and production-ready. Ship it 🚀