Skip to main content

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

FunctionAndroidiOS
signUpWithGoogle()Uses Google Sign-InNot available
signUpWithApple()Not supported (throws error)Uses Apple Sign In
signIn(['google-signin'])Uses Google Sign-InNot available
signIn(['apple-signin'])Not availableUses 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:

ParameterTypeDescriptionDefaultRequired
serverClientIdstringYour Google Web Client ID-Yes
noncestringRandom string for token validation-No
autoSelectEnabledbooleanAuto-select account if only one is availabletrueNo

Apple Sign In Parameters (iOS)

When using Apple Sign In on iOS, you can configure:

ParameterTypeDescriptionDefaultRequired
noncestringRandom string for token validation-No
requestedScopesstring[]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

  1. 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
  2. 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

  1. 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
  2. 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

  1. Token Security: Never store authentication tokens in AsyncStorage without encryption
  2. Error Handling: Implement robust error handling for sign-in failures
  3. Token Verification: Always verify tokens on your backend before granting access
  4. User Experience: Provide clear feedback during the sign-in process
  5. Account Linking: Consider how to link accounts if users sign in with different methods
  6. Token Refresh: Implement token refresh mechanisms for long-lived sessions