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,
// Show all Google accounts for sign-up (default behavior)
filterByAuthorizedAccounts: false,
});

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
filterByAuthorizedAccountsbooleanOnly show accounts that have previously authorized the appfalse for sign-up, true for sign-inNo

Account Filtering Options

The filterByAuthorizedAccounts parameter controls which Google accounts are shown to the user:

  • false (recommended for sign-up): Shows all Google accounts available on the device. Useful for new user registration or when you want to allow users to sign in with any account.
  • true (recommended for sign-in): Only shows Google accounts that have previously authorized your app. Provides a faster, more streamlined experience for returning users.

Example: Sign-Up vs Sign-In Behavior

// For new user registration - show all accounts
const signUpCredential = await signUpWithGoogle({
serverClientId: "YOUR_WEB_CLIENT_ID",
filterByAuthorizedAccounts: false, // Shows all Google accounts
});

// For returning users - show only authorized accounts
const signInCredential = await signIn(['google-signin'], {
googleSignIn: {
serverClientId: "YOUR_WEB_CLIENT_ID",
filterByAuthorizedAccounts: true, // Shows only previously authorized accounts
}
});

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,
// Only show previously authorized accounts for sign-in (default behavior)
filterByAuthorizedAccounts: 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
  3. Developer Console Error [Error: [28444] Developer console is not set up correctly.]:

    • To resolve this, try using a Web client ID instead of the Android OAuth client ID:
      1. Go to the Google Cloud Console
      2. Select your project
      3. Navigate to "APIs & Services" → "Credentials"
      4. Click "Create Credentials" and select "OAuth client ID"
      5. Choose "Web application" as the application type
      6. Give it a name (e.g., "Web client for Android")
      7. Click "Create"
      8. Copy the generated Web client ID
      9. Use this Web client ID as the serverClientId parameter in signUpWithGoogle() instead of the Android OAuth client ID

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