ionic+firebase+auth 実機(capacitor)で動かす

目的

ionic+firebase+auth で実機(ios)で動かすことが今回の目的です。

ionicを使ったプロジェクトでfirebaseを使った認証(authetification)を使用する必要があり、webでは動くのに実機では素直に動かなかったので、動くためにやったことを記事にします。

結論から言うとwebで動くfirebaseのコードは実機(capacitor)では動作しません。実機用のライブラリとコードを書く必要があります。こちらのcapacitor-firebaseのGitHubに使い方が載っていますので、そちらを見ながら参考にしてください。

capawesome-team/capacitor-firebase

では、これからcapacitorでfirebaseを動作させる準備をしていきます。

使用ライブラリ

環境構築

はじめにwebでfirebaseを使用するために、firebase上でプロジェクトを作成し、webアプリの設定(APIキーの取得)をしたと思います。実機でfirebaseを使用するには、web用のAPIではなく、ios用の別途apiへの接続情報が記載されたGoogleService-Info.plistも必要になります。

手順に関しては公式ページで解説しています。Firebase を Apple プロジェクトに追加する

ただし、注意して欲しいのが公式ページに記載されている手順のステップ 3: Firebase 構成ファイルを追加するまでで止めてください。GoogleService-Info.plistをxcodeのプロジェクトルートフォルダにコピーまでしかしなくていいです。それ以降のfirebase SDKのインストールは不要です。

実機(ios)で動くionic+firebase+auth 認証のコード

ユーザー作成(メール&パスワード)

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
    }

    async createUser(email: string, password: string): Promise<void> {
        const result = await FirebaseAuthentication.createUserWithEmailAndPassword({ email: email, password: password });
    }

}

ログイン

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
    }

    async logIn(email: string, password: string): Promise<void> {
        const ret = await FirebaseAuthentication.signInWithEmailAndPassword({ email: email, password: password });
    }

}

ユーザー名取得

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
    }

    async fetchDisplayName(): Promise<string> {
        const result = await FirebaseAuthentication.getCurrentUser();
        if (!result.user) {
            throw new Error("ユーザ情報が取得できませんでした。");
        }
        const displayName: string = result.user.displayName!;
        return displayName;
    }


}

サインアウト

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
    }

    async logout(): Promise<void> {
        await FirebaseAuthentication.signOut();
    }

}

ログイン中かどうか

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
    }

    async isLogin(): Promise<boolean> {
        return new Promise((resolve) => {
            FirebaseAuthentication.addListener("authStateChange", (result) =>
                if (result.user) {
                    resolve(true);
                } else {
                    resolve(false);
                }
            });
        });
    }

}

Web用のコードと実機用のコードを混在させる

以下のような感じでCapacitor.isNativePlatformメソッドの結果で分岐させてやれば良いです。

import { FirebaseApp, initializeApp } from "firebase/app";
import { Auth, initializeAuth, indexedDBLocalPersistence } from "firebase/auth";
import { FirebaseAuthentication } from "@capacitor-firebase/authentication";
import { Firestore, getFirestore, } from "firebase/firestore";

export class AuthService {
    private database: Firestore;
    private auth: Auth;

    constructor() {
        const firebase: FirebaseApp = initializeApp("各自のAPIの値を設定");
        this.database = getFirestore(firebase);
        if (Capacitor.isNativePlatform()) {
            this.auth = initializeAuth(firebase, { persistence: indexedDBLocalPersistence });
        } else {
            this.auth = getAuth(firebase);
        }
    }

}

まとめ

web用に書いたfirebaseの認証コードが動かないとは初め全く考えていませんでいした。うまくionicとcapacitorが吸収してくれていると思っていましたが違ったようです。ionicとfirebaseで何かする記事は多かったですが実機で動かしてみる記事が少なかったので忘れないように記事にしておきます。

他にもionicに関する記事を書いています。

コメントする