IonicでもFirebaseでSNS認証がしたい
IonicはAngularが使われているので、AngularFireを使って普通に認証処理を書くことができます。ionic serve
で動かして問題なくよしよし、と思っていたのですが予期せぬ自体が発生しました。
実機でも動かしてみようと思って手持ちの iPhone にインストールして動かしてみると動かない … 。いろいろ調べてみると、WebViewベースのアプリではセキュリティの関係でそのままだと動かないようです。
ただFirebaseの公式ページを見ると、CordovaでFirebase認証をする方法の説明がされていますし、ネットで調べると動かしているサンプルも見つかりますが、どうやってもうまくいきませんでした。
通常の方法だとうまくいかなかったので、Google認証に絞って調べて試してみたところ、@ionic-native/google-plus というプラグインを使って実装する方法でうまく行ったので、その方法をまとめます。
サンプル実装
検証環境
- Ionic 4.3.1
- Cordova Platform iOS 4.5.5
- NodeJS v10.0.0
- Angular CLI 7.0.6
- @ionic/angular 4.0.0-beta.16
iOSのエミュレーターで動作を確認します。Androidはひとまず保留です。
Ionic 4 プロジェクトの準備
まずは Ionic のプロジェクトを作成します。プロジェクトはIonic4で作ります。
$ ionic start myApp blank
Try Ionic 4? Yes
プロジェクトができたら config.xml の中身のIDを書き換えます。
<widget id="com.angularfire.ionic" ...>
IDはFirebaseのコンソールでの設定に使います。
Firebaseプロジェクトを設定する
設定値の取得
Firebaseのコンソールから新しいプロジェクトを追加します。
プロジェクト名の設定等は適宜行ってください。ここでは、angularfire-test という名前でプロジェクトを作成しました。
プロジェクトの管理画面に入って、設定値を取得します。画面の [\</>] をクリックすると Web から利用する場合の設定値が取得できます。
configの設定内容をAngularの環境設定ファイルにコピーして使います。src/app/enviroment.ts
に次のように設定してください。
export const environment = {
production: false,
firebase: {
apiKey: "xxxxxx-xxxxxxxxxxxxxxxx-xxx",
authDomain: "angularfire-test-xxxx.firebaseapp.com",
databaseURL: "https://angularfire-test-xxxxx.firebaseio.com",
projectId: "angularfire-test-xxxxx",
storageBucket: "angularfire-test-xxxxx.appspot.com",
messagingSenderId: "1234567890"
}
};
Firebase Auth のログイン方法を設定
まずはコンソールにログインし、開発メニューの中にある Authentication を開きます。[ログイン方法を設定] ボタンからこのプロジェクトで許可するログイン方法を設定していきます。
デフォルトだとすべてのログイン方法が無効になっています。今回利用する “”Google” を有効にします。
iOS用アプリ登録を行う
アプリから利用する場合、Firebaseにアプリの登録を行う必要があります。iOSアプリを追加してみます。コンソールの以下のボタンからついできます。
先程 config.xml
に設定したIDを “iOS バンドルID” の項目に設定します。その他の項目は未入力でOKです。
次に設定ファイル(GoogleService-Info.plist
)のダウンロードができるのでダウンロードしておきます。ファイルの中身を後で使います。
あとの項目は次へ次へで進めて、5の「アプリを実行してインストールを確認」はスキップして操作を完了します。これだとコンソールで設定途中というマークが付くのですが、これで動くので良しとします。
Firebase のインストール
ログイン認証自体はプラグインで行いますが、管理はFirebaseで行うのでFirebaseとAngularFireをインストールします。
$ npm install firebase @angular/fire promise-polyfill --save
@ionic-native/google-plus のインストール
Google アカウントでのログインを行うためのプラグイン @ionic-native/google-plus をインストールします。
$ npm install --save @ionic-native/google-plus@^5.0.0-beta
beta版をインストールしていますが、5.0.0 より新しいバージョンが必要です。
次にpluginを追加しますが、このとき REVERSED_CLIENT_ID
と WEB_APPLICATION_CLIENT_ID
を設定します。
$ ionic cordova plugin add cordova-plugin-googleplus --variable REVERSED_CLIENT_ID=yourReversedClientID --variable WEB_APPLICATION_CLIENT_ID=yourwebapplicationclientid
REVERSED_CLIENT_ID
は、アプリ登録時にダウンロードした GoogleService-Info.plist
ファイルに記述されています。
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.13459-xxxxxxxxxxxxxxxxx</string>
WEB_APPLICATION_CLIENT_ID
は、GCPのコンソール から取得します。よくわかっていないのですが、コンソールの以下の値をコピーします。
プラグイン追加時のパラメータはconfig.xmlに追加されているのでファイルから直接変更も可能です。
これで準備は完了です。以下実装に移ります。
app.module.ts の編集
インスールした諸々を追加していきます。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
// ここから追加分
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { GooglePlus } from '@ionic-native/google-plus/ngx';
import { environment } from 'src/environments/environment';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
AngularFireModule.initializeApp(environment.firebase), //
AngularFireAuthModule //
],
providers: [
GooglePlus, //
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
コメントした箇所が追加行です。
home.ts, home.html
home画面に にGoogleアカウントでのログインとログアウトの機能を実装します。
home.ts
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { GooglePlus } from '@ionic-native/google-plus/ngx';
import { Platform } from '@ionic/angular';
import { Observable } from 'rxjs';
import * as firebase from 'firebase';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
user: Observable<firebase.User>;
constructor(private angularFireAuth: AngularFireAuth,
private gplus: GooglePlus,
private platform: Platform) {
this.user = this.angularFireAuth.authState;
}
googleLogin() {
if (this.platform.is('cordova')) {
// Cordova環境でのみGooglePlusプラグインでログインする
this.nativeGoogleLogin();
} else {
this.webGoogleLogin();
}
}
async nativeGoogleLogin(): Promise {
try {
const gplusUser = await this.gplus.login({
'webClientId': '', // 先程GCPコンソールからコピーした値
'offline': true,
'scopes': 'profile email',
});
return await this.angularFireAuth.auth.signInWithCredential(
firebase.auth.GoogleAuthProvider.credential(gplusUser.idToken)
);
} catch(err) {
console.log(err)
}
}
async webGoogleLogin(): Promise {
try {
const provider = new firebase.auth.GoogleAuthProvider();
const credential = await this.angularFireAuth.auth.signInWithPopup(provider);
} catch(err) {
console.log(err)
}
}
logout() {
this.angularFireAuth.auth.signOut();
if (this.platform.is('cordova')) {
this.gplus.logout();
}
}
}
home.html
<ion-header>
<ion-toolbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<div *ngIf="(user | async) || {} as user">
<ion-button *ngIf="!user.uid" (click)="googleLogin()">
Login with Google
</ion-button>
<div *ngIf="user.uid">
すでにログイン済みです UID: {{ user.uid }}
<ion-button (click)="logout()">
Logout
</ion-button>
</div>
</div>
</ion-content>
ログイン時には、Cordova(Ionit)環境の場合のみプラグインでの認証を試みます。通常時(ionic serve
で開発中など)は、普通のFirebaseでのログイン方法でログインします。
プラグイン利用時は、WebClientIDが必要になります。これはプラグイン追加時の WEB_APPLICATION_CLIENT_ID
と同じ値です。
これで完了です。実機もしくはエミュレータで動作を確認してみます。
こんな感じで動くことが確認できます。
以上。
コメントを書く