実質、UaalでFirebaseSDKを組み込んでみる の続き。
普通に取得するだけならできたんですが、ログアウトしたりStateが変化したときにうまく取れなくハマったのでそのメモ。
やったこと
- OverrideUnityActivityにstatic変数でidTokenを追加(firebaseAuthIdToken)
- addAuthStateListenerでstate変更検知してcurrentUserがnull(ログアウトとかしたとき)にidTokenを消す
- addIdTokenListenerでidTokenの変更検知してidTokenを更新
- 今回のケースは、多分こっちだけあればいい気もする
- Unity側から強制的にtokenを更新できるようにするJNIを追加(refreshToken)
// OverrideUnityActivity.java
public abstract class OverrideUnityActivity extends UnityPlayerActivity
{
public static OverrideUnityActivity instance = null;
abstract protected void showMainActivity(String setToColor);
public static String firebaseAuthIdToken = "";
abstract protected void refreshToken();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
instance = this;
}
@Override
protected void onDestroy() {
super.onDestroy();
instance = null;
}
}
// MainUnityActivity.kt
class MainUnityActivity : OverrideUnityActivity() {
// Setup activity layout
override fun onCreate(savedInstanceState: Bundle?) {
...
FirebaseAuth.getInstance().addAuthStateListener { firebaseAuth: FirebaseAuth ->
if (firebaseAuth.currentUser == null) {
firebaseAuthIdToken = ""
}
}
FirebaseAuth.getInstance().addIdTokenListener { firebaseAuth: FirebaseAuth ->
firebaseAuth.currentUser?.getIdToken(false)?.addOnSuccessListener {
firebaseAuthIdToken = it.token
}
}
...
}
override fun refreshToken() {
FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnSuccessListener {
firebaseAuthIdToken = it.token
}
}
...
}
// Cube.cs
...
string getIdToken()
{
var idToken = "";
#if UNITY_ANDROID
try
{
AndroidJavaClass jc = new AndroidJavaClass("com.company.product.OverrideUnityActivity");
idToken = jc.GetStatic<string>("firebaseAuthIdToken");
} catch(Exception e)
{
appendToText("Exception during getIdToken");
appendToText(e.Message);
}
#elif UNITY_IOS || UNITY_TVOS
idToken = NativeAPI.getIdToken();
#endif
return idToken;
}
void refreshToken()
{
#if UNITY_ANDROID
try
{
AndroidJavaClass jc = new AndroidJavaClass("com.company.product.OverrideUnityActivity");
AndroidJavaObject instance = jc.GetStatic<AndroidJavaObject>("instance");
instance.Call("refreshToken");
} catch(Exception e)
{
appendToText("Exception during getIdToken");
appendToText(e.Message);
}
#elif UNITY_IOS || UNITY_TVOS
NativeAPI.refreshToken();
#endif
}
...
困ったこと
- NativeでFirebaseAuthのUIで認証したが、Unity側でgetIdTokenすると値が取得できない
- MainUnityActicityを破棄しなおすと取れた
addAuthStateListener
やaddIdTokenListener
で変更検知しようとしても一切呼ばれない- ただしMainUnityActicityで
getIdToken(true)
とかで変更した場合は呼ばれる
- ただしMainUnityActicityで
結論
MainUnityActicityを別プロセスで実行するのをやめると、いろいろ問題が解決する。
※ただし、なぜuual-exampleで別プロセス実行になっていたのかはわかってないので、これによって何かしらの副作用があるかもしれない…
// AndroidManifest.xml
...
<activity
android:name=".MainUnityActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:hardwareAccelerated="false"
// android:process=":Unity" // 別プロセスでの実行をやめる
android:label="@string/app_name"
android:screenOrientation="fullSensor" />
...
Native側でログインして、Unity側でgetIdTokenしてる様子
MainActicity(AccountFragment) | MainUnityActicity |
---|---|