Pick your app

The examples below will be updated with your app ID.

Authentication and Permissions

Sign In with Apple

Instant supports Sign In with Apple on the Web and in native applications.

#Step 1: Create App ID

  • Navigate to Certificates, Identifiers & Profiles
  • Select Identifiers
  • Click +
  • Register a new identifier → Select App IDs
  • Select a type → Select App
  • CapabilitiesSign In with Apple → Check
  • Fill in Bundle ID and Description
  • Click Register

#Step 2: Create Services ID

  • Navigate to Services IDs
  • Click +
  • Register a new identifier → Select Services IDs
  • Fill in Description and Identifier. You’ll need this Identifier later
  • Click Register

#Step 3: Configure Services ID (React Native flow)

This step is not needed for Expo.

#Step 4: Register your OAuth client with Instant

From the dashboard

From the Auth tab on the Instant dashboard:

  • Click "Add Apple Client"
  • Select a unique client name (apple by default, used in db.auth calls)
  • Fill in your "Services ID" from Step 2
  • Click "Add Apple Client"
From the terminal
npx instant-cli@latest auth client add \
--type apple --name apple --services-id <services-id>

#Step 5: Add Sign In code to your app (React Native flow)

Instant comes with support for Expo AppleAuthentication library.

Add dependency:

npx expo install expo-apple-authentication

Update app.json by adding:

{
"expo": {
"ios": {
"usesAppleSignIn": true
}
}
}

Add exp:// as a redirect origin for development with Expo:

From the dashboard

From the Auth tab on the Instant dashboard:

  • Click "Redirect Origins" → "Add an origin"
  • Add exp://
From the terminal
npx instant-cli@latest auth origin add --type custom-scheme --scheme exp://

Authenticate with Apple and then pass identityToken to Instant along with clientName from Step 4:

const [nonce] = useState('' + Math.random());
try {
// sign in with Apple
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
nonce: nonce,
});
// pass identityToken to Instant
db.auth
.signInWithIdToken({
clientName: '<clientName>',
idToken: credential.identityToken,
nonce: nonce,
})
.catch((err) => {
console.log('Error', err.body?.message, err);
});
} catch (e) {
if (e.code === 'ERR_REQUEST_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
}
}

Sign out code:

<Button
title="Sign Out"
onPress={async () => {
await db.auth.signOut();
}}
/>

Full example:

import React, { useState } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import { init, tx } from '@instantdb/react-native';
import * as AppleAuthentication from 'expo-apple-authentication';
const APP_ID = '__APP_ID__';
const db = init({ appId: APP_ID });
function App() {
return (
<>
<db.SignedIn>
<UserInfo />
</db.SignedIn>
<db.SignedOut>
<Login />
</db.SignedOut>
</>
);
}
function UserInfo() {
const user = db.useUser();
return (
<View style={styles.container}>
<Text>Hello {user.email}!</Text>
<Button
title="Sign Out"
onPress={async () => {
await db.auth.signOut();
}}
/>
</View>
);
}
function Login() {
const [nonce] = useState('' + Math.random());
return (
<View style={styles.container}>
<AppleAuthentication.AppleAuthenticationButton
buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.BLACK}
cornerRadius={5}
style={styles.button}
onPress={async () => {
try {
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
nonce: nonce,
});
// signed in
db.auth
.signInWithIdToken({
clientName: 'apple',
idToken: credential.identityToken,
nonce: nonce,
})
.catch((err) => {
console.log('Error', err.body?.message, err);
});
} catch (e) {
if (e.code === 'ERR_REQUEST_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
}
}
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
button: {
width: 200,
height: 44,
},
});
export default App;