FirebasePushNotificationPlugin icon indicating copy to clipboard operation
FirebasePushNotificationPlugin copied to clipboard

I can receive push notifications when app in in foreground and background, but not when app is swipe-killed.

Open EmanueleUniroma2 opened this issue 4 years ago • 4 comments

Hi, i'm having the issue mentioned in the title. I have a small xamarin project that uses push notifications with data payload. Here are some relevant snippets of code:

main activity image

main application image image

Code from my custom handler ` public void OnError(string error) { DebugService.log(error); }

    private IDictionary<string, object> buildLocalNotification(String title = "COLMASTER", String body = "Hai dei nuovi messaggi non letti.", String subtitle = "Clicca per accedere all'app.")
    {
        IDictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add(new KeyValuePair<string, object>("title", title));
        dictionary.Add(new KeyValuePair<string, object>("body", body));
        dictionary.Add(new KeyValuePair<string, object>("subtitle", subtitle));
        dictionary.Add(new KeyValuePair<string, object>("priority", "high"));
        dictionary.Add(new KeyValuePair<string, object>("email", FileIoService.Read("last_valid_email")));

        return dictionary;
    }

    public void launchLocalNotification(String title = "COLMASTER", String body = "Hai dei nuovi messaggi non letti.", String subtitle = "Clicca per accedere all'app.")
    {
        IDictionary<string, object> push = buildLocalNotification(title,body,subtitle);
        OnReceived(push);
    }

    public void OnOpened(NotificationResponse response)
    {
        ContextService.messages = new List<UserMessage>() { };

        if (FileIoService.Read("token") == "")
        {
            NavigationService.navigate("LoginPage");
        }
        else
        {
            NavigationService.navigate("OverviewPage");
        }
    }

    private String stringifyNotification(IDictionary<string, object> parameters)
    {
        String s = "Received push:\n\n";
        foreach (KeyValuePair<string, object> kvp in parameters)
        {
            s += kvp.Key.ToString() + ": " +kvp.Value.ToString() + "\n";
        }
        return s + "\n\n";
    }

    public void OnReceived(IDictionary<string, object> parameters)
    {
        String stringed_push = stringifyNotification(parameters);

        DebugService.log(stringed_push);

        String targetEMail = FileIoService.Read("last_valid_email");

        if(targetEMail == "") { return; }

        //parameters = fixDictionaryKeyNames(parameters);

        List<String[]> key_values = new List<string[]>() { };

        foreach (KeyValuePair<string, object> kvp in parameters)
        {
            key_values.Add(new string[] { kvp.Key.ToString(), kvp.Value.ToString() });
        }

        String email = getValueForKey(key_values, "email");

        // notification is for you
        if (targetEMail.ToLowerInvariant() == email.ToLowerInvariant())
        {
            DebugService.log("Notification accepted.");
            acceptNotification(parameters);

            stringed_push += "\n push has been accepted.\n";
        }

        DeveloperPushPage.addPush(stringed_push);

    }

    private IDictionary<string, object> fixDictionaryKeyNames(IDictionary<string, object> parameters)
    {
        IDictionary<string, object> dictionary = new Dictionary<string, object>();

        foreach (KeyValuePair<string, object> kvp in parameters)
        {
            dictionary.Add(new KeyValuePair<string, object>(kvp.Key.ToString().Replace("aps.alert.", ""), kvp.Value));
        }

        return dictionary;
    }

    /* 
     * push notification need a unique incremental id to increment the badge counter.
     * since it can happen that some id are not synked from backend due to data loss, 
     * is safer to just build a locally unique id, each time.
     * */
    private String get_incremental_notification_id()
    {

        String id = FileIoService.Read("push_incremental_id");

        int id_i = 0;

        if (id != "")
        {
            try
            {
                id_i = Int32.Parse(id);
                id_i = id_i + 1;

            }
            catch (Exception e)
            {
                DebugService.log(e);
            }
        }

        id = id_i.ToString();
        FileIoService.Write("push_incremental_id", id);

        return id;
    }



    private void acceptNotification(IDictionary<string, object> parameters)
    {
        // debug, play a sound file
        //playSound();
        if (parameters.ContainsKey("id")) {
            parameters["id"] = get_incremental_notification_id();
        }
        else
        {
            parameters.Add(new KeyValuePair<string, object>("id", get_incremental_notification_id()));
        }


        IMetrics metricsProvider = DependencyService.Get<IMetrics>();
        metricsProvider.acquirePushNotification(parameters);
    }

    private void playSound()
    {
        if (Device.RuntimePlatform == Device.Android)
        {
            DependencyService.Get<IAudio>().PlayAudioFile("ring.mp3");
        }
        else
        {
            DependencyService.Get<IAudio>().PlayAudioFile("ring.m4r");
        }
    }

    private String getValueForKey(List<String[]> key_values, String key)
    {
        foreach (String[] s in key_values)
        {
            if(s[0] == key) { return s[1]; }
        }

        return "";
    }

    public void OnAction(NotificationResponse response)
    {
        DebugService.log("On action called");   
    }
}`

Am i missing something? Why can't i get push notification on a killed app?

EmanueleUniroma2 avatar Sep 22 '20 10:09 EmanueleUniroma2

Are u trying in debug mode?

themronion avatar Sep 23 '20 13:09 themronion

yes, but also release with signed apk is not working :(

Il giorno mer 23 set 2020 alle ore 15:28 Pavlo Lukianets < [email protected]> ha scritto:

Are u trying in debug mode?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CrossGeeks/FirebasePushNotificationPlugin/issues/362#issuecomment-697364019, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGL26K5QBNXEQXQUIBGKZK3SHHZW5ANCNFSM4RVSHQKA .

EmanueleUniroma2 avatar Sep 23 '20 13:09 EmanueleUniroma2

Hi i wanted to add some info to help you guis debugging your plugin.

The plugin now works perfectly. What i did was removing my "custom handler" for push upon initialization and use instead your default handler.

I don't know where the bug is, but the plugin does not work for custom handlers only ( and only on app swipe-killed, works fine otherwise).

best regards

Il giorno mer 23 set 2020 alle ore 15:45 emanuele serrao < [email protected]> ha scritto:

yes, but also release with signed apk is not working :(

Il giorno mer 23 set 2020 alle ore 15:28 Pavlo Lukianets < [email protected]> ha scritto:

Are u trying in debug mode?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CrossGeeks/FirebasePushNotificationPlugin/issues/362#issuecomment-697364019, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGL26K5QBNXEQXQUIBGKZK3SHHZW5ANCNFSM4RVSHQKA .

EmanueleUniroma2 avatar Sep 29 '20 10:09 EmanueleUniroma2

Hi,

The problem is the FirebasePushNotificationManager uninitialized in killed apps. I have a workaround to receive push notifications in background, but generates duplicated "com.google.firebase.MESSAGING_EVENT" in AndroidManifest.xml. It works on <=Android 9 but on Android 10 always fired only the first intent filter (only PNFirebaseMessagingService fired).

Is it possible to remove "com.google.firebase.MESSAGING_EVENT" intent filter at PNFirebaseMessagingService class? And should be implement the developer in the project like bellow:

[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyMessagingService : PNFirebaseMessagingService
{
    public MyMessagingService()
    {
        if (CrossFirebasePushNotification.Current.NotificationHandler == null) // app killed!
        {
            FirebasePushNotificationManager.Initialize(Application.Context, new PushNotificationHandler(), false, false, false);
        }
    }
}

It have to work in foreground, background and killed apps on all android versions.

xilard avatar Nov 19 '20 09:11 xilard