- Published on
Set Up Appwrite Auth with Apple Login in Expo (2025 Guide)
- Authors
- Name
- Ahmed Farid
- @
TIP
Bookmark this page when adding social logins to your Expo projects—Apple demands strict guidelines and this checklist keeps you compliant.
Appwrite offers a unified auth layer, while Expo simplifies cross-platform builds. Apple, however, imposes special requirements for OAuth. This guide details all steps to connect Sign in with Apple to Appwrite Auth in an Expo SDK 50+ project.
Table of Contents
- Table of Contents
- 1. Prerequisites & Terminology
- 2. Create an Expo Project & Install Dependencies
- 3. Set Up Apple Credentials in Developer Portal
- 4. Configure Appwrite OAuth Provider
- 5. Add OAuth Callback to Allowed URLs
- 6. Configure iOS Entitlements & Info.plist
- 7. Initialising Appwrite SDK
- 8. Implement Sign in with Apple Flow
- 9. Handling First-Time Name/Email
- 10. Testing on Simulator & Real Device
- 11. Adding Web Support (Optional)
- 12. Production Checklist
- 13. Troubleshooting
- 14. Further Reading & Resources
- 15. Conclusion
1. Prerequisites & Terminology
- Appwrite 1.4+ self-hosted or Cloud project.
- Expo SDK 50 (managed workflow).
- macOS with Xcode 15 for Apple Developer portal.
- An Apple Developer account ($99/year).
Term | Meaning |
---|---|
Service ID | Identifier used by Apple for web / native OAuth flows |
Key ID | Identifier for the private key that signs JWTs |
Client Secret | JWT signed with your private key; validates token exchange |
expo-apple-authentication | Expo module exposing AppleAuthentication API |
2. Create an Expo Project & Install Dependencies
npx create-expo-app AppleAuthApp
cd AppleAuthApp
yarn add expo-apple-authentication react-native-appwrite
npx expo prebuild --platform ios # generates native xcode project for entitlements
NOTE
On bare workflow you can skip prebuild
—just ensure the Apple entitlement file is updated (see §6).
3. Set Up Apple Credentials in Developer Portal
- Identifiers → App IDs: Create com.yourco.appleauthapp.
- Enable Sign In with Apple capability.
- Keys → +: Create Sign In with Apple key, select the above App ID.
- Download the
.p8
file—store securely. - Note Key ID and Team ID (Organization). You’ll use them in Appwrite.
- Identifiers → Service IDs: Create com.yourco.appleauthapp.service.
- Configure Primary App ID = your app.
- Under Web Authentication Configuration add https://YOUR_APPWRITE_ENDPOINT/v1/account/sessions/oauth2/callback/apple as redirect.
4. Configure Appwrite OAuth Provider
Dashboard → Auth / Providers / Apple:
- Team ID
- Key ID
- Private Key (paste
.p8
contents) - Bundle ID = com.yourco.appleauthapp
- Callback URL (auto-filled) → Add same in Apple dashboard.
- Scopes:
name
,email
(Apple only returns once—store immediately).
Save → Appwrite now lists APPLE
as active provider.
5. Add OAuth Callback to Allowed URLs
Project settings → API / Platforms → iOS → add appscheme://auth for deep links.
Also add https://auth.expo.dev/@yourname/AppleAuthApp if you later use EAS AuthSession.
6. Configure iOS Entitlements & Info.plist
The Expo config plugin handles this automatically:
// app.json
{
"expo": {
"ios": {
"bundleIdentifier": "com.yourco.appleauthapp",
"usesAppleSignIn": true,
},
},
}
Regenerate with npx expo prebuild --platform ios
after updates.
7. Initialising Appwrite SDK
// src/lib/appwrite.ts
import { Client, Account, Avatars } from 'react-native-appwrite'
export const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('YOUR_PROJECT_ID')
export const account = new Account(client)
8. Implement Sign in with Apple Flow
// src/screens/Login.tsx
import * as Apple from 'expo-apple-authentication'
import { account } from '@/lib/appwrite'
import * as AuthSession from 'expo-auth-session'
import { useState } from 'react'
import { View, Text, Button, Alert } from 'react-native'
export default function Login() {
const [loading, setLoading] = useState(false)
const loginWithApple = async () => {
setLoading(true)
try {
// 1. Open Apple Authentication prompt
const credential = await Apple.signInAsync({
requestedScopes: [
Apple.AppleAuthenticationScope.FULL_NAME,
Apple.AppleAuthenticationScope.EMAIL,
],
})
// 2. Exchange identity token with Appwrite
const session = await account.createOAuth2Session(credential.identityToken!, 'apple')
console.log('Logged in ✨', session)
} catch (err: any) {
console.error(err)
Alert.alert('Login failed', err.message)
} finally {
setLoading(false)
}
}
return (
<View className="flex-1 items-center justify-center px-4">
<Text className="mb-4 text-2xl">Apple Login Demo</Text>
<Apple.AppleAuthenticationButton
buttonType={Apple.AppleAuthenticationButtonType.SIGN_IN}
buttonStyle={Apple.AppleAuthenticationButtonStyle.BLACK}
cornerRadius={8}
style={{ width: 280, height: 45 }}
onPress={loginWithApple}
disabled={loading}
/>
</View>
)
}
Key points:
identityToken
comes from Apple—JWT withsub
.createOAuth2Session
acceptstoken
,provider
("apple"), optional redirect (we bypass by performing exchange client-side).- Store the returned session or JWT in secure storage.
9. Handling First-Time Name/Email
Apple returns name/email once. Appwrite stores them automatically, but if you need to save display name in your DB, capture from credential.fullName
during first login.
if (credential.fullName?.givenName) {
await account.updateName(`${credential.fullName.givenName} ${credential.fullName.familyName}`)
}
10. Testing on Simulator & Real Device
- Simulator with Xcode 15 supports Apple Sign In.
- Ensure Settings → Apple ID → iCloud signed in.
- On TestFlight, Apple requires Sign in with Apple justification if other social logins exist.
11. Adding Web Support (Optional)
For Expo Web, use AuthSession:
const redirectUri = AuthSession.makeRedirectUri({ useProxy: true })
await AuthSession.startAsync({
authUrl: `https://cloud.appwrite.io/v1/account/sessions/oauth2/apple?project=YOUR_PROJECT_ID&success=${redirectUri}`,
})
Appwrite will redirect back with #access_token=
fragment. Parse and create stored session.
12. Production Checklist
✅ App Clip disabled unless needed. ✅ usesAppleSignIn: true
in Expo config. ✅ Privacy policy links in App Store Connect. ✅ Store user email immediately—Apple may hide it (private relay
). ✅ Support account deletion (App Store rule §5.1.1).
13. Troubleshooting
Issue | Fix |
---|---|
Error: invalid_client | Check Key ID / Team ID mismatch in Appwrite |
Identity token null | Apple prompt cancelled; guard against aborts |
Appwrite 401 | Project ID wrong or platform not allowed |
14. Further Reading & Resources
- Appwrite OAuth providers.
- Expo module
expo-apple-authentication
. - Apple Developer Sign In with Apple JS.
15. Conclusion
You now have an end-to-end Sign in with Apple flow powered by Appwrite and Expo—covering certificates, entitlements, token exchange and UI. Happy shipping! 🚀