3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UnityからFirebase(主にFunctionsとAuth)のEmulatorを触ろうとしてハマった

Posted at

馴れ初め

個人ゲームのデータをFirebaseのFireStoreにFunctions経由で保存しようとした
開発段階だからとemulatorをセッティングし、Unityからアクセスしようとした

つまづき

sdkのemulatorの対応状況がバラバラ
emulatorの設定メソッドくらい用意してください・・・

状況

Firebaseのemnulatorをセットアップし、Unityのsdkを入手した。
さて、emulatorに繋ごうとしてドキュメントを見ると

FireStore ⇨ settingsでemulatorに接続するように設定できる(ちょっとトリッキー)
Functions ⇨useFunctionEmulator というメソッドが用意されている(ちゃんとしてる)
authentication ⇨ねーよ

Google?

こまるポイントその1

authがGoogle鯖に繋ぎにいくので、

cureateUser.cs
 auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task => {

とすると、普通にGoogleサーバにauthのユーザーが作られます。
(簡単すぎてびびるくらい)
そう、emulatorにはユーザーが作られない(当たり前)
でも、開発中はローカルのemulatorでやりたいわけです
色々試行錯誤するも、結局、emulatorコンソールまたは、functionsでメソッド書いてできた

こまるポイントその2

非同期処理が色々面倒ですが、Functionsもauthもsdkの使い方は簡単で
認証処理をして(省略)、サーバ接続のコードを書く(省略)と、接続時に認証情報を渡してくれるようです
(認証情報を自分で渡す必要がないらしい)

signIn.cs
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
}
//hogehoge
await functions.GetHttpsCallable("helloWorld")
            .CallAsync(hogeData)
            .ContinueWith(task => {
            // HogeHoge
            }
    );

こうすることで、サーバ側にはcontextにauthとして情報が渡ります
多分、一般的にはサーバ側ではユーザーが認証されてる(auth情報を使う)かどうかを確かめて処理を動かすので

index.js
exports.helloWorld = functions.https.onCall((data, context) => {
    if (context.auth === undefined || !context.auth.uid || context.auth.uid === 0) {
        throw new functions.https.HttpsError('unauthenticated');
    }
    return admin.auth().getUser(userId)
        .then(() => {
        // HogeHoge
        }};

ととなるかと思います。これは、Google鯖上では普通に動きます。
が、emulator上ではgetUser で例外がスローされます。ユーザーないので・・・

とりあえずの回避法

ローカルでの開発中はgetUserをすっ飛ばす

は、流石に強引すぎるので。
1)auth emulatorに authと同じユーザーIDでユーザーを作る
2)クライアントでは、auth認証で得られたuserIdをなんらかの方法でFunctionsに渡す
  (今回は普通にデータに突っ込んだ)
3)Functions側ではemulatorで動いているかをチェックして、emulatorの場合は、
context.auth.uidの代わりに、送られてきたユーザーIDを使う

という回避方法を使ってみた

index.js
    var userId = context.auth.uid;
    if (process.env.FUNCTIONS_EMULATOR === 'true') {
        userId = data.userId;
    }
    return admin.auth().getUser(userId)
    // HogeHogeな処理

結論

そもそもこれで正しいのかググってもあまり出てこない。が、開発中部分なんで良いんでは、という気がしている
(個人ゲームだし!)
困ってる人があまりいない、ということは、UnityでFirebaseを使う際にAuthentication使ってないのかなぁ

お願い

正しい(と思われる)方法があったら教えてください。
あとGoogleの人はさっさとUnitySDKにuseEmulatorを実装してください。
FireStoreも正式なメソッドではなく、Settingsメソッドでなんとかしてますよねぇ

蛇足

ちなみに、

useEmulator.swift
func useEmulator(withHost host: String, port: Int)
useEmulator.java
FirebaseAuth.useEmulator(withHost host: String, port: Int)

とネイティブ版にはあるので、ネイティブプラグインを使えばできそうですが、
このためにそこまでやる?
って感じなのでやめました

なお、Functions自身はonCallを使うととっても簡単にサーバとやり取りできます
UnityのWebRequestでJSONでうんたらこうたらするより随分簡単でした
(どのみち非同期処理はいるんだけど・・・)

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?