expo-google-sign-in provides native Google authentication for standalone Expo apps or bare React Native apps. It cannot be used in the Expo client as the native GoogleSignIn library expects your REVERSED_CLIENT_ID in the info.plist at build-time. To use Google authentication in the Expo client, check out expo-google-app-auth or expo-app-auth.
Create a native iOS app using the ios.bundleIdentifier you defined earlier, and an Android app using the android.package.
(Android only) Go to your Firebase project's settings, scroll down to "Your apps" and select your Android app. Under SHA certificate fingerprints, click Add fingerprint, and paste the value of you get for Google Certificate Fingerprint when running expo fetch:android:hashes.
If you haven't already run expo build:android for this project, you'll need to do that first before getting the Google Certificate Fingerprint.
Download the GoogleService-Info.plist (iOS) & the google-services.json (Android) from your Firebase project settings page. Move them to your Expo project.
In app.json, set your expo.ios.config.googleSignIn.reservedClientId to the value of REVERSED_CLIENT_ID in the GoogleService-Info.plist.
Also in app.json, set expo.ios.googleServicesFile to the relative path of your GoogleService-Info.plist. Make sure the file is located somewhere in your Expo project.
And also in app.json, set expo.android.googleServicesFile to the relative path of your google-services.json. Make sure the file is located somewhere in your Expo project.
// app.json{"expo":{"ios":{// The bundle ID you used with your Firebase app"bundleIdentifier":"example.expo.googlesignin","config":{"googleSignIn":{// Your REVERSED_CLIENT_ID from the GoogleService-Info.plist"reservedClientId":"<YOUR_REVERSED_IOS_CLIENT_ID>"}},// Optional path to the iOS file generated by Firebase"googleServicesFile":"./GoogleService-Info.plist"},"android":{// The package you used with your Firebase app"package":"example.expo.googlesignin",// Optional path to the Android file generated by Firebase"googleServicesFile":"./google-services.json"}}}
At this point you can build your project and upload it to the App Store or the Google Play Store.
When your app is built you can verify that the iOS URL Scheme is properly set up by reading it using the expo-app-auth module in a standalone app.
import*asAppAuthfrom'expo-app-auth';// When configured correctly, URLSchemes should contain your REVERSED_CLIENT_IDconst{URLSchemes}=AppAuth;
importReactfrom'react';import{Text}from'react-native';import*asGoogleSignInfrom'expo-google-sign-in';exportdefaultclassAuthScreenextendsReact.Component{
state ={ user:null};componentDidMount(){this.initAsync();}initAsync=async()=>{awaitGoogleSignIn.initAsync({// You may ommit the clientId when the firebase `googleServicesFile` is configured
clientId:'<YOUR_IOS_CLIENT_ID>',});this._syncUserWithStateAsync();};_syncUserWithStateAsync=async()=>{const user =awaitGoogleSignIn.signInSilentlyAsync();this.setState({ user });};signOutAsync=async()=>{awaitGoogleSignIn.signOutAsync();this.setState({ user:null});};signInAsync=async()=>{try{awaitGoogleSignIn.askForPlayServicesAsync();const{ type, user }=awaitGoogleSignIn.signInAsync();if(type ==='success'){this._syncUserWithStateAsync();}}catch({ message }){alert('login: Error:'+ message);}};onPress=()=>{if(this.state.user){this.signOutAsync();}else{this.signInAsync();}};render(){return<Text onPress={this.onPress}>ToggleAuth</Text>;}}
Before using the API we first need to call GoogleSignIn.initAsync({ ... }) which configures how sign in functionality will work.
try{awaitGoogleSignIn.initAsync({// You may ommit the clientId when the firebase `googleServicesFile` is configured
clientId:'<YOUR_IOS_CLIENT_ID>',// Provide other custom options...});}catch({ message }){alert('GoogleSignIn.initAsync(): '+ message);}
Android Only, this method always returns true on iOS
Use this method to determine if a user's device can utilize Google Sign-In functionality.
By default this method will assume the option is false and silently check for Play Services, whereas passing true will present a modal if the Play Services aren't available, prompting the user to update Play Services.
Android Only, this method always returns true on iOS
A convenience wrapper for GoogleSignIn.getPlayServiceAvailability(true), this method will present a modal for the user to update Play Services if they aren't already up-to-date.
This method will attempt to reauthenticate the user without initializing the authentication flow. If the method is successful, the currently authenticated GoogleUser will be returned, otherwise the method will return null.
On Android, the returned GoogleUser object may have a nonnull serverAuthCode rather than a refreshToken. If you need a refresh token, you can call Google's API directly to exchange the authorization code for a token. Instructions for how to perform this request can be found in Google's documentation ("Step 5: Exchange authorization code for refresh and access tokens"). The clientId in these requests is the Web Client ID from the Google API Console.
Starts the native authentication flow with the information provided in GoogleSignIn.initAsync().
If a user cancels, the method will return { type: 'cancel', user: null }. However if a user successfully finishes the authentication flow, the returned value will be: { type: 'success', user: GoogleUser }.
There are some errors that can be thrown while authenticating, check GoogleSignIn.ERRORS for available error codes.
Signs out the currently authenticated user. Unlike GoogleSignIn.disconnectAsync(), this method will not revoke the access token. This means you can specify the accountName and reauthenticate without extra user approval.
Signs out the current user and revokes the access tokens associated with the account. This will prevent reauthentication, whereas GoogleSignIn.signOutAsync() will not.
Returns an image URI for the currently authenticated user. This method will return null if no user is signed in, or if the current user doesn't have a profile image on Google.
The default size is 128px, if the requested image size is larger than the original image size, the full sized image will be returned.
/* Android Only */
type GoogleSignInType='default'|'games';
type GoogleSignInOptions={/*
* [iOS][Android][optional]: `accountName: ?string`
* [default]: `[GoogleSignIn.SCOPES.PROFILE, GoogleSignIn.SCOPES.EMAIL]`
* Pass the scopes you wish to have access to.
*/
scopes:?Array<string>,/*
* [iOS][Android][optional]: `webClientId: ?string`
* [default]: `undefined`
* The client ID of the home web server. This will be returned as the |audience| property of the
* OpenID Connect ID token. For more info on the ID token:
* https://developers.google.com/identity/sign-in/ios/backend-auth
*/
webClientId:?string,/*
* [iOS][Android][optional]: `hostedDomain: ?string`
* [default]: `undefined`
* The hosted G Suite domain of the user. Provided only if the user belongs to a hosted domain.
*/
hostedDomain:?string,/*
* [iOS][Android][optional]: `accountName: ?string`
* [default]: `undefined`
* If you know the user's email address ahead of time, you can add it here and it will be the default option
* if the user has approved access for this app, the Auth will return instantly.
*/
accountName:?string,/*
* [Android][optional]: `signInType?: GoogleSignIn.TYPES.DEFAULT | GoogleSignIn.TYPES.GAMES`
* [default]: `undefined`
* The service you wish to sign in to
* GoogleSignIn.TYPES.DEFAULT | GoogleSignIn.TYPES.GAMES
*/
signInType:?GoogleSignInType,/*
* [Android][optional]: `isOfflineEnabled: ?boolean`
* [default]: `undefined`
* If true, the server will return refresh tokens that can be used to access data when the user has unauthenticated.
* 1. Safely secure the refresh token as you can only get one during the initial auth flow.
* 2. There are only so many refresh tokens that are issued, limit per user/app, you can also get one for a single user across all clients in an app. If you requests too many tokens, older tokens will begin to be invalidated.
*/
isOfflineEnabled:?boolean,/*
* [Android][optional]: `isPromptEnabled: ?boolean`
* [default]: false
* Forces the consent prompt to be shown everytime a user authenticates. Enable this only when necessary.
*/
isPromptEnabled:?boolean,/*
* [iOS][optional]: `clientId: ?string`
* [default]: Read from GoogleService-Info.plist `CLIENT_ID` on iOS, and google-services.json `oauth_client.client_id` on Android.
* The client ID of the app from the Google APIs (or Firebase) console, this must be set for sign in to work.
* This value must be defined in the google-services.json on Android, you can define your custom google-services.json
*/
clientId:?string,/*
* [iOS][optional]: `language: ?string`
* [default]: `undefined`
* The language for sign in, in the form of ISO 639-1 language code optionally followed by a dash
* and ISO 3166-1 alpha-2 region code, such as |@"it"| or |@"pt-PT"|. Only set if different from
* system default.
*/
language:?string,/*
* [iOS][optional]: `openIdRealm?: ?string`
* [default]: `undefined`
* The OpenID2 realm of the home web server. This allows Google to include the user's OpenID
* Identifier in the OpenID Connect ID token..
*/
openIdRealm:?string,};
type GoogleSignInAuthResultType='success'|'cancel';
type GoogleSignInAuthResult={
type:GoogleSignInAuthResultType,
user:?User,};