ChrizTalk

Ionic 2 and Firebase Google authentication

February 7, 2017ChrizIonic9 comments
If you like it, please share it:

This post is based on my previous post Ionic 2 and Firebase authentication.

You can download the code on GitHub at https://github.com/henkie14/ionic2Firebase. Make sure you change the Firebase configuration in the app.module.ts file.

In this post I will continue working on the project above and add native Google authentication to the Ionic app.

Start by getting the package name (or widget id) from your config.xml file (in the root of your application).

package name ionic config xml

Open your firebase console at https://console.firebase.google.com and go to your project overview.

First we will do the iOS version.

add Firebase to iOS app

Select iOS configuration.

add Firebase to iOS app step 1

Add your package name you got from the config.xml above and add the app.

add Firebase to iOS app step 2

The GoogleService-info.plist file will be downloaded, and you should get the REVERSE_CLIENTID from the file.
Skip the rest of the configuration steps by closing the wizard.

GoogleService-list.plist reversed-client-id

 

Now you can install the plugin by using the iOS REVERSE_CLIENTID.

ionic plugin add cordova-plugin-googleplus --save --variable REVERSED_CLIENT_ID=com.googleusercontent.apps.*********************

Next is the Android version.

First of all you need to get an SHA-1 fingerprint.
There’s is very good guide by Google : https://developers.google.com/android/guides/client-auth.

Next go to your Firebase console, project overview and add the Android configuration.

Add Firebase to Android app

First add a new application.

Add Firebase to Android app

Select Android.

 

Add Firebase to Android app step 1

Add the package name from the config.xml and the SHA-fingerprint you generated before.

Add Firebase to Android app step 2

You can now close the wizard.

The file google-services.json will be downloaded, copy it to your project, you will need some data from it in a later stage and get webclient_id for auth-provider.ts

If you didn’t install the iOS version above, install the plugin now. (You can get the REVERSED_CLIENT_ID from the google developer console at https://console.developers.google.com/apis/credentials, select your project and get the OAuth 2.0-client-ID for Android. something like ***************.apps.googleusercontent.com

ionic plugin add cordova-plugin-googleplus --save --variable REVERSED_CLIENT_ID=***************.apps.googleusercontent.com

Now we need to update the Ionic application to use the installed plugin.

Let’s add a Google login button to the home page, open up your home.html and change it like this:

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic2Firebase
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
    <ion-title>Login</ion-title>
    <ion-row>
        <ion-item>
            
<div *ngIf="auth.authState">current user is {{auth.currentUser}}</div>
        </ion-item>
    </ion-row>
    
<form [formGroup]="loginForm" (ngSubmit)="submit()" novalidate>
        <ion-row>
            <ion-item>
                <ion-label for="email"></ion-label>
                <ion-input type="email" value="" placeholder="Email" formControlName="email"></ion-input>
            </ion-item>
        </ion-row>
        <ion-row>
            <ion-item>
                <ion-label for="password"></ion-label>
                <ion-input type="password" placeholder="Password" formControlName="password"></ion-input>
            </ion-item>
        </ion-row>
    </form>
    <ion-row>
        <button (click)="login()" ion-button block>Log in</button>
    </ion-row>
    <ion-row> 
        <button [navPush]="signupPage" ion-button block>Sign up</button>
    </ion-row>
    <!--new link to sign up page-->
    <ion-row> 
        <button [navPush]="resetPasswordPage" ion-button block>Reset password</button>
    </ion-row>
    <ion-row> 
        <button (click)="logout()" ion-button block>Log out</button>
    </ion-row>
    <ion-row> 
        <button (click)="loginWithGoogle()" ion-button block>Google login</button>
    </ion-row>
</ion-content>

And add the loginWithGoogle method to home.ts.

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { NavController } from 'ionic-angular';
import { AuthProvider } from '../../providers/auth-provider';
import { SignupPage } from '../signup/signup' 
import { ResetPasswordPage } from '../reset-password/reset-password' //Added reset password page
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  loginForm: FormGroup;
  email: AbstractControl;
  password: AbstractControl;
  error: any;
  signupPage = SignupPage; 
  resetPasswordPage = ResetPasswordPage //Added reset password page
  constructor(private navCtrl: NavController, private fb: FormBuilder, private auth: AuthProvider) {
    this.loginForm = this.fb.group({  
            'email': ['', Validators.compose([Validators.required, Validators.pattern(/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/)])],
            'password': ['', Validators.compose([Validators.required, Validators.minLength(1)])]
        });
 
    this.email = this.loginForm.controls['email'];     
    this.password = this.loginForm.controls['password'];
  }
  loginWithGoogle(): void{
    this.auth.loginWithGoogle().subscribe((success) => {
      console.log(success);
    }, err => {
      console.log(err);
    });
  }
  login(): void { 
      if(this.loginForm.valid) {
        var credentials = ({email: this.email.value, password: this.password.value});
        this.auth.loginWithEmail(credentials).subscribe(data => {
          console.log(data);
        }, error=>{
          console.log(error);
          if (error.code == 'auth/user-not-found')
          {
            alert('User not found');
          }
        });
      }
    }
    logout(): void {
      this.auth.logout();
    }
}

Last part is the implementation on the authorization provider. Change auth-provider.ts like this:

import { Injectable, EventEmitter, Inject } from '@angular/core';
import { AuthProviders, AngularFire, FirebaseAuthState, AuthMethods, FirebaseApp } from 'angularfire2'; //Add FirebaseApp
import { Observable } from "rxjs/Observable";
import { Platform } from 'ionic-angular';
import { GooglePlus } from 'ionic-native';
import { auth } from 'firebase'; //needed for the GoogleAuthProvider

@Injectable()
export class AuthProvider {
  private authState: FirebaseAuthState;
  public onAuth: EventEmitter<FirebaseAuthState> = new EventEmitter();
  public firebase : any;
  
  constructor(private af: AngularFire, @Inject(FirebaseApp)firebase: any,private platform: Platform) { //Add platform
    this.firebase = firebase;  
    this.af.auth.subscribe((state: FirebaseAuthState) => {
      this.authState = state;
      this.onAuth.emit(state);
    });
  }
  loginWithGoogle() {
    return Observable.create(observer => {
      if (this.platform.is('cordova')) {
       return GooglePlus.login({
          'webClientId':'******************.apps.googleusercontent.com' //your Android reverse client id
        }).then(userData => {
          var token = userData.idToken;
          const googleCredential = auth.GoogleAuthProvider.credential(token, null);
          this.firebase.auth().signInWithCredential(googleCredential).then((success)=>{
            observer.next(success);
          }).catch(error => {
            //console.log(error);
            observer.error(error);
          });
        }).catch(error => {
            //console.log(error);
            observer.error(error);
        });
      } else {
        return this.af.auth.login({
          provider: AuthProviders.Google,
          method: AuthMethods.Popup
          }).then(()=>{
            observer.next();
          }).catch(error => {
            //console.log(error);
            observer.error(error);
        });
      }
    });
  }
  loginWithEmail(credentials) {
    return Observable.create(observer => {
      this.af.auth.login(credentials, {
        provider: AuthProviders.Password,
        method: AuthMethods.Password
      }).then((authData) => {
        //console.log(authData);
        observer.next(authData);
      }).catch((error) => {
        observer.error(error);
      });
    });
  }
  registerUser(credentials: any) {
    return Observable.create(observer => {
      this.af.auth.createUser(credentials).then(authData => {
        //authData.auth.updateProfile({displayName: credentials.displayName, photoURL: credentials.photoUrl}); //set name and photo
        observer.next(authData);
      }).catch(error => {
        //console.log(error);
        observer.error(error);
      });
    });
  }
  
  resetPassword(emailAddress:string){
    return Observable.create(observer => {
      this.firebase.auth().sendPasswordResetEmail(emailAddress).then(function(success) {
          //console.log('email sent', success);
          observer.next(success);
        }, function(error) {
          //console.log('error sending email',error);
          observer.error(error);
        });
     });
  }
  logout() {
    this.af.auth.logout();
  }
  get currentUser():string{
    return this.authState?this.authState.auth.email:'';
  } 
}

IMPORTANT:The webclient id on line 27 should be replaced by the client_id from the google-services.json you downloaded previously.
google-services.json webclient-id

There’s a lot going on here, let me explain.
There’s an import of Platform, that’s being used to check on what platform the app is running, based on the platform we will call the native Google login or a pop-up.
The Google import is used for calling the native Google plugin.
The auth import from Firebase is needed since AngularFire2 doesn’t have support for the GoogleProvider (yet).
This is why it’s important to use the correct firebase (3.3.0) and angularfire2 (2.0.0-beta.6) versions. Otherwise you might end up with a lot of ‘Duplicate identifier’ errors.

Ok, let’s run the application to see if it’s working. First test it in your browser.

$ionic serve

When you try to login by Google you will see the following error:

The given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Auth section.

So let’s go to the Firebase console again at https://console.firebase.google.com and select your project.
Next select Authentication on the left hand side and click the tab ‘Sign in method’.

Firebase enable Google sign-in

Firebase enable Google sign-in
Click Google and enable it.

Let’s test it again in your browser.

$ionic serve

When you click the Google login button you should see a popup where you can connect with your Google account and when you login, it should show the corresponding email address as the current user.
You can also check the users tab on the authentication menu in the Firebase console to see all registered users and their provider.

Now let’s try it on android to see if the native Google functionality is working. Connect you Android phone and run the following commands.

$ionic platform add android
$ionic run android

If things don’t seem to work or you see the following Firebase error: auth/network-request-failed. Try this:

$ionic platform rm android
$ionic platform add android

You can try it out on iOS by connecting you iOS device and run:

$ionic platform add ios
$ionic run ios

Please leave a message if you got it working or not or things aren’t clear or whatever 🙂

That’s all folks.

The next post will be about getting data from and to Firebase…


If you like it, please share it:
Previous Post Ionic 2 and Firebase Facebook authentication Next Post Using Google Fonts in Ionic 2

9 comments. Leave new

Abhimanyu
March 31, 2017 10:11 pm

getting error in this line Cresential marked as an error

const googleCredential = auth.GoogleAuthProvider.credential(token, null);

Reply
Chriz
April 6, 2017 7:22 pm

If you can sent me some extra information, I can have a look at it.

Reply
Keshav
April 6, 2017 12:31 am

Hi Chris,
Thanks for the post. I’m getting ‘12501’ error on android device when I replace webClientId on line 27 with ‘client_id’ of ‘client_type’:1 from google-services.json but if I switch to ‘client_id’ for ‘web’ (client_type: 3) then it works on both browser and android device.

Reply
Hudhud
May 8, 2017 3:11 pm

Hello,

I get the following error:

[ts]
Type ‘EventEmitter’ is not assignable to type ‘EventEmitter’.
Type ‘{}’ is not assignable to type ‘FirebaseAuthState’.
Property ‘uid’ is missing in type ‘{}’.

On “public onAuth: EventEmitter = new EventEmitter();”

What is wrong?

Reply
Hudhud
May 9, 2017 4:01 pm

Have solved this by writing this instead: public onAuth: EventEmitter = new EventEmitter();

Reply
Hudhud
May 9, 2017 4:00 pm

Hello Chris,
Thanks for taking the time to post this. However, when building the project for Android I keep getting the error:
Error: cmd: Command failed with exit code 1 Error output:
C:\Users\User\Documents\MyApp\platforms\android\src\nl\xservices\plugins\GooglePlus.java:346: error: cannot find symbol
cordova.getActivity(), acct.getAccount(), true

What is wrong? Have followed the tutorial.

Reply
almog ka
July 3, 2017 1:50 pm

thank you for that great tutorial .
1.in web when i sign in with google i get undefined in success response.
2.i have problem when i try to see in emulator android i see black screen.
3.when i try to see the app in view ionic app , when i click google login so nothing happen .

please help me , waiting for answer .

Thank you !

Reply
almog ka
July 3, 2017 1:58 pm

i get error “plugin_not_installed” when i click google login in on ionic view app on android

Reply
Mark
November 14, 2017 10:17 am

Thanks for the tutorial Chris!
On web, everything is working just fine. Unfortunately, when running on an Android device, I keep receiving error 10. After debugging and checking certificates, I’m kinda stuck. Any suggestions/experiences with this issues?

Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Ionic 3 and Firebase Facebook authentication using AngularFire2
  • Ionic 3 and Firebase authentication using AngularFire2
  • Ionic 3, Firebase and AngularFire2
  • Ionic 2 and Font Awesome using Sass
  • Using Google Fonts in Ionic 2

My Ionic 2 Theme

Please have a look at my new Ionic 2 theme.

&copy 2016 ChrizTalk