firebase / quickstart-unity

Firebase Quickstart Samples for Unity
https://firebase.google.com/games
Apache License 2.0
819 stars 424 forks source link

Not receiving the Push Notifications on iOS #1375

Open Morgan-6Freedom opened 3 days ago

Morgan-6Freedom commented 3 days ago

[REQUIRED] Please fill in the following fields:

[REQUIRED] Please describe the issue here:

(Please list the full steps to reproduce the issue. Include device logs, Unity logs, and stack traces if available.)

Steps to reproduce:

I had this error on iOS : No APNS token specified before fetching FCM Token

I changed

 async void InitializeFirebase()
    {
        FirebaseMessaging.MessageReceived += OnMessageReceived;
        FirebaseMessaging.TokenReceived += OnTokenReceived;

        await FirebaseMessaging.SubscribeAsync(topic).ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        Log("Firebase Messaging Initialized");

        // On iOS, this will display the prompt to request permission to receive
        // notifications if the prompt has not already been displayed before. (If
        // the user already responded to the prompt, thier decision is cached by
        // the OS and can be changed in the OS settings).
        // On Android, this will return successfully immediately, as there is no
        // equivalent system logic to run.
        await FirebaseMessaging.RequestPermissionAsync().ContinueWithOnMainThread(
          task => {
              LogTaskCompletion(task, "RequestPermissionAsync");
          }
        );
        isFirebaseInitialized = true;
    }

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

to

async void InitializeFirebase()
    {
        FirebaseMessaging.MessageReceived += OnMessageReceived;
        await RegenerateFcmToken();

        await FirebaseMessaging.SubscribeAsync(topic).ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        Log("Firebase Messaging Initialized");

        // On iOS, this will display the prompt to request permission to receive
        // notifications if the prompt has not already been displayed before. (If
        // the user already responded to the prompt, thier decision is cached by
        // the OS and can be changed in the OS settings).
        // On Android, this will return successfully immediately, as there is no
        // equivalent system logic to run.
        await FirebaseMessaging.RequestPermissionAsync().ContinueWithOnMainThread(
          task => {
              LogTaskCompletion(task, "RequestPermissionAsync");
          }
        );
        isFirebaseInitialized = true;
    }

private async Task RegenerateFcmToken()
{
    try
    {
        Log("Requesting new FCM Registration Token ...");
        await FirebaseMessaging.DeleteTokenAsync();
        await FirebaseMessaging.GetTokenAsync().ContinueWithOnMainThread(task =>
        {
            if (task.Exception != null)
            {
                Log(task.Exception.Message);
                return;
            }

            fcmToken = task.Result;
            Log("Received Registration Token: " + fcmToken);

        });

    }
    catch (Exception e)
    {
        Log(e.Message);
        throw;
    }
}

And I don't have the error anymore. However, I still can't receive notification push on my iOS Device

Remote Notification is checked & Push Notification is here.

image

UserNotifications.framework is here too

image2

my APN key is uploaded in Firebase : image3

Relevant Code:

this is my FCM.cs script which is some copy paste from yours from the sample :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Messaging;
using TMPro;
using System.Net;
using Firebase.Extensions;
using System;
using System.Threading.Tasks;

public class FCM : MonoBehaviour
{
    [SerializeField] TextMeshProUGUI messageText;

    bool isFirebaseInitialized;
    string fcmToken = "";
    string topic = "dates";
    Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;

    async public void Start()
    {
        Debug.Log("IN START");

        await Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
            dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                Log("Firebase available");
                InitializeFirebase();
            }
            else
            {
                Debug.LogError(
                  "Could not resolve all Firebase dependencies: " + dependencyStatus);
            }
        });
    }

    // Setup message event handlers.
    async void InitializeFirebase()
    {
        FirebaseMessaging.MessageReceived += OnMessageReceived;
        /*
#if UNITY_IPHONE
        FirebaseMessaging.TokenReceived += OnTokenReceived;
#endif
#if UNITY_ANDROID*/
        await RegenerateFcmToken();
//endif

        await FirebaseMessaging.SubscribeAsync(topic).ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        Log("Firebase Messaging Initialized");

        // On iOS, this will display the prompt to request permission to receive
        // notifications if the prompt has not already been displayed before. (If
        // the user already responded to the prompt, thier decision is cached by
        // the OS and can be changed in the OS settings).
        // On Android, this will return successfully immediately, as there is no
        // equivalent system logic to run.
        await FirebaseMessaging.RequestPermissionAsync().ContinueWithOnMainThread(
          task => {
              LogTaskCompletion(task, "RequestPermissionAsync");
          }
        );
        isFirebaseInitialized = true;
    }

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

    private async Task RegenerateFcmToken()
    {
        try
        {
            //bug connu, le token n'est pas régénéré par défaut : https://github.com/firebase/quickstart-unity/issues/1088
            Log("Requesting new FCM Registration Token ...");
            await FirebaseMessaging.DeleteTokenAsync();
            await FirebaseMessaging.GetTokenAsync().ContinueWithOnMainThread(task =>
            {
                if (task.Exception != null)
                {
                    Log(task.Exception.Message);
                    return;
                }

                fcmToken = task.Result;
                Log("Received Registration Token: " + fcmToken);

                //On pourrait appeler une cloud function ici pour stocker ce token dans Firestore pour envoyer des notifications ciblées
            });

        }
        catch (Exception e)
        {
            Log(e.Message);
            throw;
        }
    }

    public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
    {
        Log("Received a new message");
        Log($"Message opened : {e.Message.NotificationOpened}\n", true);
        var notification = e.Message.Notification;
        if (notification != null)
        {
            Log("title: " + notification.Title, true);
            Log("body: " + notification.Body, true);
            var android = notification.Android;
            if (android != null)
            {
                Log("android channel_id: " + android.ChannelId, true);
            }
        }
        if (e.Message.From.Length > 0)
        {
            Log("from: " + e.Message.From, true);
        }

        if (e.Message.Link != null)
        {
            Log("link: " + e.Message.Link.ToString(), true);
        }
        if (e.Message.Data.Count > 0)
        {
            Log("data:", true);
            foreach (KeyValuePair<string, string> iter in
                     e.Message.Data)
            {
                Log("  " + iter.Key + ": " + iter.Value, true);
            }
        }
    }

    void Log(string message, bool newLine = false)
    {
        if (newLine)
        {
            messageText.text += $"\n{message}";
            Debug.Log(message);
        }
        else
        {
            Debug.Log(messageText.text = message);
        }
    }

    // Log the result of the specified task, returning true if the task
    // completed successfully, false otherwise.
    protected bool LogTaskCompletion(Task task, string operation)
    {
        bool complete = false;
        if (task.IsCanceled)
        {
            Log(operation + " canceled.");
        }
        else if (task.IsFaulted)
        {
            Log(operation + " encounted an error.");
            foreach (Exception exception in task.Exception.Flatten().InnerExceptions)
            {
                string errorCode = "";
                Firebase.FirebaseException firebaseEx = exception as Firebase.FirebaseException;
                if (firebaseEx != null)
                {
                    errorCode = string.Format("Error.{0}: ",
                      ((Firebase.Messaging.Error)firebaseEx.ErrorCode).ToString());
                }
                Log(errorCode + exception.ToString());
            }
        }
        else if (task.IsCompleted)
        {
            Log(operation + " completed");
            complete = true;
        }
        return complete;
    }

    public async void UI_DeleteCurrentToken()
    {
        Log("Deleting current FCM Token...");
        await Firebase.Messaging.FirebaseMessaging.DeleteTokenAsync();
        Log("FCM Token deleted.");
    }

    public async void UI_GetNewToken()
    {
        Log("Requesting new FCM Token...");
        await Firebase.Messaging.FirebaseMessaging.GetTokenAsync().ContinueWithOnMainThread(task =>
        {
            if (task.Exception != null)
            {
                Log(task.Exception.Message);
                return;
            }

            fcmToken = task.Result;
            Log("Received Registration Token: " + fcmToken);

            //On pourrait appeler une cloud function ici pour stocker ce token dans Firestore pour envoyer des notifications ciblées
        });
    }

    public async void UI_SubscribeToDates()
    {
        Log("Pressed subscribe..."); 
        await FirebaseMessaging.SubscribeAsync(topic).ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        await FirebaseMessaging.SubscribeAsync($"/topics/{topic}").ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        Log("Subscribed to dates");
    }

    public async void UI_UnsubscribeFromDates()
    {
        Log("Pressed unsubscribe...");
        await FirebaseMessaging.UnsubscribeAsync(topic).ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        await FirebaseMessaging.UnsubscribeAsync($"/topics/{topic}").ContinueWithOnMainThread(task => {
            LogTaskCompletion(task, "SubscribeAsync");
        });
        Log("Unsubscribed from dates");
    }
}