firebase / firebase-unity-sdk

The Firebase SDK for Unity
http://firebase.google.com
Apache License 2.0
203 stars 35 forks source link

[Question] What should I do to get Push Notifications on iOS ? #1060

Closed Morgan-6Freedom closed 3 weeks ago

Morgan-6Freedom commented 1 month ago

What is your question?

[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);
    }

[/code]

to

[code=CSharp]    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");
    }
}

Firebase Unity SDK Version

12.1

Unity editor version

2022.3.30

Installation Method

.unitypackage

Problematic Firebase Component(s)

Messaging

Other Firebase Component(s) in use

No response

Additional SDKs you are using

No response

Targeted Platform(s)

Apple Platforms

Unity editor platform

Mac, Windows

Scripting Runtime

IL2CPP

Release Distribution Type

Pre-built SDK from https://firebase.google.com/download/unity

argzdev commented 3 weeks ago

Hey @Morgan-6Freedom, sorry for the delayed response. So I was able to take a look into your code, it seems that there isn't any problem. I've also tested our Firebase Unity Quickstart and it seems like it is working alright. I'm guessing the issue might be that you haven't added the APNs Authentication Key in the Firebase Console. You're going to have to follow a guide here from the iOS section:

Upload your APNs authentication key to Firebase. If you don't already have an APNs authentication key, make sure to create one in the Apple Developer Member Center.

  • Inside your project in the Firebase console, select the gear icon, select Project Settings, and then select the Cloud Messaging tab.
  • In APNs authentication key under iOS app configuration, click the Upload button.
  • Browse to the location where you saved your key, select it, and click Open. Add the key ID for the key (available in the Apple Developer Member Center) and click Upload.

Feel free to use our quickstart for testing the Firebase Messaging. You can also take a look into the README section of the FCM quickstart to get a step by step instruction how to set it up.

For now, it looks like there isn't a problem with the SDK, so I'll go ahead and close this thread. Feel free to come back here if you think there's an issue with the SDK. Thanks!

Morgan-6Freedom commented 3 weeks ago

The issue was : I putted the Key ID as Key ID & Team ID. Instead of Key ID as Key ID only.

(1) & (2) were the same value. which is not correct image