ElectronでFirebaseAuthを利用するにはいくつか問題があります。
まず、大前提としてFirebase公式はElectronへのサポートを提供していない事を理解しておきましょう。
その他にも、Electronは通常fileプロトコルでアプリケーションを動かす事が多いですが、その状態でFirebaseAuth(もっというとGoogleAPIなど)を利用しようとしても
対応してるプロトコルはhttpかhttps、もしくはChromeExtensionで、その他にWebストレージを有効にする必要があります。
と怒られます。
今回利用したいのはFirebaseAuth(Googleアカウント認証/認可)のみですが、FirebaseのリアルタイムDBやFirestoreでも同じように対応することで利用出来ると思います、ただし検証はしていないのでAuth以外を使う方はあくまで参考程度にしてください。
Electronアプリが既に存在する前提で話を進めていきます。
ElectronアプリにExpressモジュールを追加してローカルサーバーを建てる
httpモジュール使えば新規にExpressモジュールを追加する必要はありませんが、簡単なのでExpressをインストールします。
また、既にElectronアプリがhttp/httpsで読み込んでいる場合はこの章はスキップできます。
Electronアプリのディレクトリで以下を実行し、Expressを追加します。
% npm i express
インストールが完了したら、Electronのエントリーポイントとなるファイル、通常はアプリディレクトリにあるmain.js、にExpressでサーバーを建てるためのプログラムを追加します。
const express = require('express');
const exp = express();
exp.use(express.static('./'));
exp.listen(8080);
ポートは任意の開いてる所を選んでください。
このコードを書くことでElectronアプリにブラウザからもlocalhost:8080
でアクセスできるようになります。
main.jsの中のファイルをロードしている部分を以下のように書き換えましょう。
//win.loadFile('index.html'); //筆者はこのようにファイルを読み込んでいた
win.loadURL('http://localhost:8080'); //このようにlocalhost:8080を読むように変更する
% electron .
コマンドでアプリを起動すると、fileを読んでいた時と同じように画面が表示されるはずです。
Firebaseのセットアップ
プロジェクトは事前に作成し、GoogleAuthを有効にしておいてください。
アプリケーションにFirebaseモジュールを追加しましょう。
既に追加している方はスキップしてください。
% npm i firebase
基本的に、モジュールを追加した後にアプリで利用するには以下のコード
const firebase = require('firebase');
を記述しますが、今回は無視してください。書かなくても問題無いです。
インストールしたら、index.htmlのheadに以下のコードを追加します。
<script src="./node_modules/firebase/firebase.js"></script>
<script src="./node_modules/firebase/firebase-app.js"></script>
<script src="./node_modules/firebase/firebase-auth.js"></script>
これにより、JavaScriptファイル内でrequireからインポートしなくても、firebaseオブジェクトが利用できるようになります。
FirebaseAuth部分の処理を書く
筆者の環境は、自分で設置したbutton要素をクリックすると、ログイン処理が走るようになっているので、その前提で進めて行きます。
<button id="google_auth">Googleログイン</button>
const authButton = document.getElementById("auth_button");
authButton.addEventListener("click", () => {auth()}, false);
上記のように、Googleログインボタンをクリックすると、authという関数が呼ばれます。
まずauth関数の前に、firebaseオブジェクトを利用するには、初期化処理が必要です。
初期化に必要な情報はFirebaseプロジェクトの設定から確認できるので、自身の情報に置き換えて読んでください。
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
databaseURL: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx"
};
firebase.initializeApp(firebaseConfig);
これでfirebaseオブジェクトが利用可能になるので、authの実装をしていきます。
const auth = async () => {
const provider = new firebase.auth.GoogleAuthProvider();
const auth = await firebase.auth().signInWithPopup(provider);
if (auth.user != null && auth.user.email != null) {
console.table({uid: auth.user.uid, email: auth.user.email});
}
};
これで準備がほぼ整いました。
筆者は認証にsignInWithPopup()
を使用しています。
Electronアプリでこのようにポップアップを利用するには、main.js内でインスタンス化されているBrowserWindowに値がtrue
なwebPreferences.nativeWindowOpen
プロパティを渡す必要があります。
let win;
function createWindow () {
win = new BrowserWindow({
width: 1200,
height: 1000,
webPreferences: {
nativeWindowOpen: true, //ここ
nodeIntegration: true
}
});
win.loadURL('http://localhost:8080');
win.webContents.openDevTools();
win.on('closed', () => {
win = null;
});
}
app.on('ready', createWindow);
ここまでやって、ついに準備が整いました。
Electronアプリを起動して、「Googleログイン」ボタンをクリックすると、ポップアップウィンドウが表示され、馴染み深いGoogleログイン画面が表示されます。
ログインを終えると、ポップアップウィンドウが閉じられ、開発者ツールのコンソール画面にユーザーIDとログインしたユーザーのメールアドレスが表示されます。
お疲れさまでした。