FirebaseCloudMessagingとUnityのMobileNotificationsを使った際にサンプル通りにやったらうまくいかなかった話

AvatarPosted by

この記事はGRIPHONE Advent Calendar 2019 15日目の記事です

こんにちは。Unityエンジニアの上岡です。
今回は、Push通知実装時に
グローバルPushにFirebaseCloudMessaging
ローカルPushにUnityのMobileNotifications
を使用した際に、サンプル通りに実装してみたらうまくいかなかったので
そのときの対応方法の話をします。

FirebaseCloudMessagingとMobileNotificationの組み込み

とりあえず、FirebaseCloudMessagingの公式ドキュメントに従って実装したソースがこちらです。

    void Awake()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
            }
            else
            {
                UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
            }
        });
    }

    void Start()
    {
        Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
        Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
    }

    public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
    {
        UnityEngine.Debug.Log("Received Registration Token: " + token.Token);
    }

    public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
    {
        UnityEngine.Debug.Log("Received a new message from: " + e.Message.From);
    }

これでFirebaseのコンソールから通知を送ると、問題なく受信することができます。

次に、MobileNotificationの初期化を組み込んでみます。

   void Awake()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
            }
            else
            {
                UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
            }
        });
    }

    void Start()
    {
        Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
        Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;

        // ローカルpushの初期化
        AndroidNotificationCenter.RegisterNotificationChannel(new AndroidNotificationChannel
        {
            Id = "test channel",
            Name = "テストチャンネル",
            Importance = Importance.High,
            Description = "テストのチャンネル",
        });
    }

    public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
    {
        UnityEngine.Debug.Log("Received Registration Token: " + token.Token);
    }

    public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
    {
        UnityEngine.Debug.Log("Received a new message from: " + e.Message.From);
    }

ローカルプッシュの送信のコードは

        _Button.onClick.AddListener(() =>
        {
            AndroidNotificationCenter.SendNotification(
                new AndroidNotification
                {
                    Title = "ローカルプッシュテスト",
                    Text = "テスト",
                    FireTime = System.DateTime.Now.AddSeconds(10)
                },
                "test channel");
        });

こうなります。
これで問題なく動作するはずなのですが
実際に動作確認すると、グローバルプッシュは問題なく動作しますが
ローカルプッシュが動作しませんでした。

原因を探るため、FirebaseCloudMessagingを外してMobileNotificationsだけでテストすると問題なく動きました。

色々と調べたのですが、参考になるものもほぼ見つからなかったので
この手の問題は大抵初期化周りだろうと思って色々やってみた結果なんとかなりました。

実際の修正内容

修正したコードがこちら

    void Awake()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
                Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
            }
            else
            {
                UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
            }
        });
    }

    void Start()
    {
        // ローカルpushの初期化
        AndroidNotificationCenter.RegisterNotificationChannel(new AndroidNotificationChannel
        {
            Id = "test channel",
            Name = "テストチャンネル",
            Importance = Importance.High,
            Description = "テストのチャンネル",
        });
    }

変更したのは
Start()でやっていた、CloudMessagingのイベントハンドラ登録を移動しただけです。
Awake()でやっている処理は、ドキュメントによると
Google Play 開発者サービスの要件を確認する
といった処理らしいのですが、これの確認が終わるのをきちんと待つべきではないかと予想しました。

しかし、これによってなぜMobileNotificationsのローカルプッシュが動かなくなるのかは謎なままです。

おわりに

UnityのMobileNotificationsはわりと最近previewが外れて使えるようになったようなので
調べてもまだ情報があまりでてきません。
実装自体は簡単なのでUnityでローカルPushを実装する場合には使われていくようになるのではないかと予想しています。

あまりいないかもですが、同じ問題で躓いている人の助けになれれば幸いです。