This article was originally published on Jo4 Blog.
"Just run eas build --platform ios --auto-submit and you're done!"
Famous last words.
The Problem
I had a React Native app built with Expo. Android was already live on the Play Store. iOS should be the same process, right?
Here's what actually happened over the next 4 hours.
Part 1: The Provisioning Profile Dance
First build attempt:
❌ Provisioning profile doesn't support the App Groups capability
My app has a Share Extension (for sharing URLs from other apps). Share Extensions need their own bundle ID, their own provisioning profile, and their own set of capabilities.
The fix:
- Go to Apple Developer Portal → Identifiers
- Find both your main app ID AND the ShareExtension ID
- Enable "App Groups" capability on BOTH
- Go to Profiles → Delete the old profiles
- Let EAS regenerate them
EAS will ask to create new profiles. Say yes. It knows what it's doing (mostly).
Part 2: Sign in with Apple - The Checkbox That Wasn't
Apple requires apps with third-party login to also offer Sign in with Apple. My app uses Auth0, which supports Apple auth. Should be simple.
Build attempt #2:
❌ Disabled: Sign In with Apple
The app.config.js was missing one line:
ios: {
// ... other config
usesAppleSignIn: true // This one. This is the line.
}
Added it, rebuilt. Profile regenerated with the capability. Build succeeded.
Part 3: The "invalid_client" Mystery
App built. App ran. Tapped "Sign in with Apple."
invalid_client
Checked Auth0 config. Everything looked right:
- Client ID:
io.jo4.mobile✓ - Team ID: correct ✓
- Key ID: correct ✓
- Private key: pasted from .p8 file ✓
Spent 30 minutes rechecking these values.
Turns out, the Apple Sign in Key I created had empty "Enabled Services". The key existed but wasn't actually configured for Sign in with Apple.
The fix:
- Apple Developer → Keys → Click your key → Edit
- Check "Sign in with Apple"
- Click Configure → Select your app as Primary App ID
- Save
Tried again:
invalid_request
Invalid client id or web redirect url
Different error. Progress.
Part 4: Services ID - The Thing Auth0 Docs Bury
Here's what I didn't understand: Auth0 uses a web-based OAuth flow for Apple Sign in (via Universal Login). This means Apple sees it as a web app, not a native app.
Web apps need a Services ID, not just an App ID.
The fix:
- Apple Developer → Identifiers → Create Services ID
- Name it something like
io.jo4.mobile.auth0 - Enable "Sign in with Apple"
-
Configure with:
- Primary App ID: Your main app
- Domains:
your-tenant.us.auth0.com - Return URLs:
https://your-tenant.us.auth0.com/login/callback
Update Auth0's Apple connection to use the Services ID as the Client ID
Finally:
✅ Sign in with Apple works
The Complete Checklist
For anyone doing this in the future:
Apple Developer Portal
- [ ] App ID has "Sign in with Apple" capability
- [ ] App ID has "App Groups" capability (if using extensions)
- [ ] ShareExtension ID has matching capabilities
- [ ] Key created with "Sign in with Apple" enabled
- [ ] Key configured with correct Primary App ID
- [ ] Services ID created (for Auth0/web-based flows)
- [ ] Services ID configured with Auth0 domain and callback URL
app.config.js (Expo)
ios: {
bundleIdentifier: "your.bundle.id",
usesAppleSignIn: true,
entitlements: {
"com.apple.security.application-groups": [
"group.your.bundle.id"
]
}
}
Auth0
- [ ] Apple connection uses Services ID as Client ID (not App ID)
- [ ] Team ID, Key ID, and private key are correct
EAS
- [ ] Delete old provisioning profiles if capabilities changed
- [ ] Let EAS regenerate profiles with new capabilities
Lessons Learned
EAS is magic, until it isn't. The happy path is genuinely one command. The unhappy path is a maze of Apple portals.
Capabilities cascade. If your main app needs a capability, your extensions probably do too.
Auth0 + Apple = Services ID. This isn't obvious from either company's docs. Web-based OAuth flows need a Services ID, not an App ID.
Apple's error messages lie. "invalid_client" can mean the key isn't configured. "invalid_request" can mean you need a Services ID. Neither error tells you this.
The App Store submission is the easy part. Once EAS builds successfully with
--auto-submit, it just... works. The hard part is getting that first successful build.
Building a mobile app? Save yourself the debugging session and bookmark this checklist.
Building jo4.io - a URL shortener with a mobile app that now actually exists on the App Store.
Top comments (0)