Platform Sign-In
This guide covers how to implement platform-specific authentication methods using React Native Credentials Manager, providing a unified API that automatically handles the differences between platforms.
Platform-Specific Authentication
React Native Credentials Manager provides cross-platform compatibility by supporting:
- Google Sign-In on Android
- Apple Sign In on iOS
This approach leverages each platform's native authentication capabilities while providing a consistent developer experience.
Platform Sign-In Mapping
Function | Android | iOS |
---|---|---|
signUpWithGoogle() | Uses Google Sign-In | Not available |
signUpWithApple() | Not supported (throws error) | Uses Apple Sign In |
signIn(['google-signin']) | Uses Google Sign-In | Not available |
signIn(['apple-signin']) | Not available | Uses Apple Sign In |
Cross-Platform Implementation
Platform-Specific Sign-Up
For platform-specific authentication:
import {
Platform,
signUpWithGoogle,
signUpWithApple,
} from "react-native-credentials-manager";
async function platformSpecificSignUp() {
try {
if (Platform.OS === "android") {
// Android: Google Sign-In
const googleCredential = await signUpWithGoogle({
serverClientId: "YOUR_WEB_CLIENT_ID",
nonce: "OPTIONAL_NONCE_FOR_SECURITY",
autoSelectEnabled: true,
});
return {
type: "google",
token: googleCredential.idToken,
id: googleCredential.id,
user: {
name: googleCredential.displayName,
givenName: googleCredential.givenName,
familyName: googleCredential.familyName,
photo: googleCredential.profilePicture,
},
};
} else {
// iOS: Apple Sign In
const appleCredential = await signUpWithApple({
nonce: "OPTIONAL_NONCE_FOR_SECURITY",
requestedScopes: ["fullName", "email"],
});
return {
type: "apple",
token: appleCredential.idToken,
id: appleCredential.id,
user: {
name: appleCredential.displayName,
givenName: appleCredential.givenName,
familyName: appleCredential.familyName,
email: appleCredential.email,
},
};
}
} catch (error) {
console.error("Platform-specific sign-up failed:", error);
throw error;
}
}
Google Sign-In Parameters (Android)
When using Google Sign-In on Android, you can configure:
Parameter | Type | Description | Default | Required |
---|---|---|---|---|
serverClientId | string | Your Google Web Client ID | - | Yes |
nonce | string | Random string for token validation | - | No |
autoSelectEnabled | boolean | Auto-select account if only one is available | true | No |
Apple Sign In Parameters (iOS)
When using Apple Sign In on iOS, you can configure:
Parameter | Type | Description | Default | Required |
---|---|---|---|---|
nonce | string | Random string for token validation | - | No |
requestedScopes | string[] | Requested user information | ['fullName', 'email'] | No |
Using Sign-In with Multiple Methods
You can combine platform sign-in with other authentication methods:
import { signIn, Platform } from "react-native-credentials-manager";
async function multiMethodSignIn() {
try {
const methods = ["passkeys", "password"];
// Add platform-specific method
if (Platform.OS === "android") {
methods.push("google-signin");
} else {
methods.push("apple-signin");
}
const params = {
passkeys: {
challenge: "BASE64_ENCODED_CHALLENGE",
rpId: "yourdomain.com",
timeout: 60000,
userVerification: "required",
},
};
// Add platform-specific parameters
if (Platform.OS === "android") {
params.googleSignIn = {
serverClientId: "YOUR_WEB_CLIENT_ID",
autoSelectEnabled: true,
};
} else {
params.appleSignIn = {
requestedScopes: ["fullName", "email"],
};
}
const credential = await signIn(methods, params);
// Handle different credential types
switch (credential.type) {
case "google-signin":
// Handle Google credential
return handleGoogleSignIn(credential);
case "apple-signin":
// Handle Apple credential
return handleAppleSignIn(credential);
default:
// Handle other credential types
return handleOtherCredential(credential);
}
} catch (error) {
console.error("Multi-method sign-in failed:", error);
throw error;
}
}
Credential Response Types
Google Credential (Android)
The GoogleCredential
object includes:
{
type: 'google-signin';
id: string; // Google user ID
idToken: string; // JWT token for authentication
displayName?: string;
familyName?: string;
givenName?: string;
profilePicture?: string;
phoneNumber?: string;
}
Apple Credential (iOS)
The AppleCredential
object includes:
{
type: 'apple-signin';
id: string; // Apple user ID
idToken: string; // JWT token for authentication
displayName?: string;
familyName?: string;
givenName?: string;
email?: string;
}
Backend Integration
After obtaining a credential, you'll need to validate the token on your backend:
Google Sign-In Verification
// Server-side code (Node.js example)
const { OAuth2Client } = require("google-auth-library");
const client = new OAuth2Client(YOUR_WEB_CLIENT_ID);
async function verifyGoogleToken(token) {
try {
const ticket = await client.verifyIdToken({
idToken: token,
audience: YOUR_WEB_CLIENT_ID,
});
const payload = ticket.getPayload();
const userId = payload["sub"];
return {
userId,
email: payload["email"],
name: payload["name"],
// Other user info...
};
} catch (error) {
console.error("Token verification failed:", error);
throw error;
}
}
Apple Sign In Verification
// Server-side code (Node.js example)
const jwt = require("jsonwebtoken");
const jwksClient = require("jwks-rsa");
const client = jwksClient({
jwksUri: "https://appleid.apple.com/auth/keys",
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
async function verifyAppleToken(token) {
return new Promise((resolve, reject) => {
jwt.verify(
token,
getKey,
{
algorithms: ["RS256"],
audience: YOUR_APP_ID, // e.g. 'com.yourcompany.yourapp'
issuer: "https://appleid.apple.com",
},
(err, payload) => {
if (err) {
return reject(err);
}
resolve({
userId: payload.sub,
email: payload.email,
// Other user info...
});
}
);
});
}
Sign Out
To sign out the user:
import { signOut, Platform } from "react-native-credentials-manager";
async function handleSignOut() {
try {
await signOut();
console.log("Sign out successful");
// Note: On iOS, this is a no-op as Authentication Services
// doesn't provide a sign-out method. You should handle
// sign-out logic in your app separately.
// Clear local auth state
clearLocalAuthState();
} catch (error) {
console.error("Sign out failed:", error);
}
}
Troubleshooting
Android Issues
-
Google Sign-In Not Working:
- Verify your Google Cloud Console setup
- Ensure your Web Client ID is correct
- Check that Google Play Services is up to date
- Confirm the user has a Google account on their device
-
No Credentials Available Error:
- This occurs when using an emulator without Google accounts
- Add a Google account to your emulator or test on a physical device
iOS Issues
-
Apple Sign In Not Working:
- Verify the Sign In with Apple capability is enabled in Xcode
- Ensure your Apple Developer account has Sign In with Apple enabled
- Check for any error messages in the Xcode console
-
Missing User Information:
- Apple may not provide all user information (like email) on subsequent sign-ins
- Store user details after the first successful sign-in
Best Practices
- Token Security: Never store authentication tokens in AsyncStorage without encryption
- Error Handling: Implement robust error handling for sign-in failures
- Token Verification: Always verify tokens on your backend before granting access
- User Experience: Provide clear feedback during the sign-in process
- Account Linking: Consider how to link accounts if users sign in with different methods
- Token Refresh: Implement token refresh mechanisms for long-lived sessions