A modern, high-performance React Native Google Sign-In library built exclusively for Turbo Modules with automatic configuration detection.
⚠️ Important: This package requires React Native New Architecture (TurboModules) and does NOT support the legacy bridge architecture.
- 🚀 Turbo Modules: Built with React Native's new architecture for maximum performance
- 🔧 Automatic Configuration: Auto-detects client IDs from
google-services.jsonandGoogleService-Info.plist - 📱 Cross-Platform: Full support for iOS and Android with platform-optimized implementations
- 🔒 Security First: Built-in nonce support and secure credential management
- ��� Optimized Performance: Thread-safe operations with intelligent caching and resource management
- 🔌 Expo Ready: Includes Expo config plugin for seamless integration
- React Native 0.79+ with New Architecture enabled
- iOS 15.1+
- Android API 24+
- Google Play Services (Android)
npm install @novastera-oss/rn-google-signin
# or
yarn add @novastera-oss/rn-google-signinConfigure the library with your Google client IDs:
import { GoogleSignin } from '@novastera-oss/rn-google-signin';
// Manual configuration (recommended)
await GoogleSignin.configure({
webClientId: 'your-web-client-id.apps.googleusercontent.com',
androidClientId: 'your-android-client-id.apps.googleusercontent.com',
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
});
// Automatic detection (fallback only)
await GoogleSignin.configure({});// Sign in
try {
const userInfo = await GoogleSignin.signIn({});
console.log('User info:', userInfo);
} catch (error) {
console.error('Sign in error:', error);
}
// Sign out
await GoogleSignin.signOut();// ✅ Correct - always pass the parameter
await GoogleSignin.signIn({});
await GoogleSignin.hasPlayServices({});
// ❌ Incorrect - will cause runtime errors
await GoogleSignin.signIn();
await GoogleSignin.hasPlayServices();Note: When using default configuration, pass {} as the parameter. When using custom options, pass an object with the desired configuration.
Provide your Google client IDs explicitly:
await GoogleSignin.configure({
// Android (choose one)
androidClientId: 'your-android-client-id.apps.googleusercontent.com',
webClientId: 'your-web-client-id.apps.googleusercontent.com',
// iOS
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
});The library can automatically detect client IDs from configuration files as a fallback:
Android:
google-services.jsoninandroid/app/directory- Uses Google Services plugin to generate
R.string.default_web_client_id
iOS:
GoogleService-Info.plistin your iOS project- Extracts
CLIENT_IDfrom the plist file
Note: Automatic detection is provided as a convenience fallback. For production apps, explicit configuration is recommended for better control and reliability.
Add the plugin without options to your app.json or app.config.js:
{
"expo": {
"plugins": [
"@novastera-oss/rn-google-signin"
]
}
}Requirements for Automatic Mode:
- Place
google-services.jsonin your project root (same level asapp.json) - Place
GoogleService-Info.plistin your project root (same level asapp.json) - Reference them in your
app.jsonconfiguration:
{
"expo": {
"ios": {
"googleServicesFile": "./GoogleService-Info.plist"
},
"android": {
"googleServicesFile": "./google-services.json"
}
"plugins": [
[
"@novastera-oss/rn-google-signin",
]
]
}
}Add the plugin with options to your app.json or app.config.js:
{
"expo": {
"plugins": [
[
"@novastera-oss/rn-google-signin",
{
"iosUrlScheme": "com.googleusercontent.apps.your-ios-client-id"
}
]
]
}
}Requirements for Manual Mode:
- The plugin only adds URL schemes, no file handling
- If you don't provide client IDs in your configuration, you must manually add
GoogleService-Info.plistto your iOS project
Complete Manual Configuration Example:
{
"expo": {
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp",
"supportsTablet": true,
"infoPlist": {
"CFBundleURLTypes": [
{
"CFBundleURLSchemes": [
"com.googleusercontent.apps.your-ios-client-id"
]
},
{
"CFBundleURLSchemes": [
"com.yourcompany.yourapp"
]
}
],
"GIDClientID": "your-ios-client-id.apps.googleusercontent.com",
"UIBackgroundModes": ["fetch", "remote-notification"]
},
"entitlements": {
"aps-environment": "development"
}
}
}
}Note: Replace your-ios-client-id with your actual iOS client ID from Google Cloud Console.
- Full Scope Support: Add additional scopes after sign-in
- Complete Token Management: Access to both access and ID tokens
- Rich User Profile: Complete user information including photos
- Modern Credential Manager: Uses Google's latest Credential Manager API
- Optimized Performance: Thread-safe operations with intelligent caching
- Basic Authentication: Focused on core sign-in functionality
⚠️ Important:isSignedIn()may trigger the credential picker UI even when the user is already signed in. This is a limitation of Google's Credential Manager API. Consider implementing your own sign-in state management for better user experience.
| Feature | iOS | Android | Notes |
|---|---|---|---|
| Basic Sign-In | ✅ | ✅ | |
| Sign Out | ✅ | ✅ | |
| Get Current User | ✅ | ✅ | |
| isSignedIn | ✅ | Android: may trigger credential picker UI | |
| Add Scopes | ✅ | ❌ | Android: Credential Manager limitation |
| Access Token | ✅ | Android: same as ID token | |
| Custom Scopes | ✅ | ❌ | Android: not supported |
This library includes several performance optimizations:
- Atomic Operations: Uses
AtomicReferencefor thread-safe promise management - Single Executor: Consistent threading model with dedicated executor
- Weak References: Prevents memory leaks with proper lifecycle management
- Credential Manager Caching: Avoids recreation on every operation by caching with activity matching
- Activity Validation: Smart activity state checking with early returns
- Promise Deduplication: Prevents concurrent operations by cancelling previous promises
- Manual Configuration Priority: Explicit client IDs take precedence over automatic detection
- Automatic Detection Fallback: Graceful fallback to config files when manual config not provided
- Multiple Resource Names: Tries various resource names for compatibility
- Graceful Fallback: Never crashes, always falls back gracefully
interface ConfigureParams {
webClientId?: string; // Web client ID
androidClientId?: string; // Android client ID
iosClientId?: string; // iOS client ID
scopes?: string[]; // Initial scopes (iOS only)
}interface User {
id: string;
name: string;
email: string;
photo?: string;
familyName?: string;
givenName?: string;
}interface SignInResponse {
user: User;
scopes: string[];
serverAuthCode?: string;
idToken?: string;
}try {
await GoogleSignin.signIn({});
} catch (error: any) {
switch (error.code) {
case 'sign_in_cancelled':
// User cancelled
break;
case 'sign_in_required':
// Sign in required
break;
case 'not_configured':
// Not configured
break;
case 'network_error':
// Network error
break;
default:
console.error('Sign in error:', error);
}
}- "No client ID found": Ensure configuration files are in the correct location
- "No activity available": Make sure the app is in the foreground
- "TurboModule not found": Ensure New Architecture is enabled
# iOS
cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
# Android - Add to android/gradle.properties
newArchEnabled=true- Place
google-services.jsoninandroid/app/ - Ensure Google Play Services is installed
- Add a Google account in device settings
- Add
GoogleService-Info.plistto your iOS project - Ensure bundle identifier matches Google Cloud Console
- Enable Google Sign-In capability
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
A: This is a common issue with production APK builds. Add these permissions to your app's android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application>
<!-- Your app configuration -->
</application>
</manifest>Also ensure your package name in android/app/build.gradle matches your Google Cloud Console configuration and add your production SHA-1 fingerprint:
cd android && ./gradlew signingReportNote: For apps already published on Google Play Store, you can also find the SHA-1 fingerprint in the Play Console under Release > Setup > App integrity.
A: This is a limitation of Google's Credential Manager API. Consider implementing your own sign-in state management for better user experience.
A: The library focuses on providing the core Google Sign-In functionality while keeping things simple. Here's the reasoning behind these design decisions:
No UI Button:
- UI components would need customization to match different app designs
- Most apps already have their own design systems and UI components
- Keeps the package focused on authentication logic
Built-in Secure Storage:
- iOS: Google Sign-In SDK uses Keychain Services for secure token storage
- Android: Credential Manager uses Encrypted SharedPreferences with AES-256 encryption
- Both platforms have built-in token management with secure storage
- No need for additional storage libraries for basic token management
- You can still use additional storage libraries if you need custom features
No Token Parsing:
- JavaScript has built-in functions to parse JSON efficiently
- Different applications handle tokens differently based on their needs
- Would add another dependency and create parsing you might re-parse anyway
- Keeps the package lightweight
This approach aims to keep dependencies minimal while providing the raw data you need to implement your app's specific requirements.
A: TurboModules don't support Swift natively yet. Using Swift would require the code to be bridged to Objective-C, which adds unnecessary overhead and complexity. Objective-C provides direct compatibility with TurboModules without any bridging layer, resulting in better performance and simpler integration.
This module is actively used in the mobile app of Novastera.com, ensuring reliability and real-world production environments.
Apache License - see LICENSE file for details.