【问题标题】:OnMessageReceived equivalent for notifications sent while app is closed / in backgroundOnMessageReceived 等效于应用程序关闭/在后台发送的通知
【发布时间】:2020-04-21 00:36:44
【问题描述】:

我想知道我可以在哪个类中指定如何处理在应用程序关闭或在后台发送时发送的通知。现在我在本地收到通知,然后触发我的SendLocalNotification 方法以按照我想要的方式构建它,这也是我希望在应用程序关闭或在后台也发生通知的情况。我仍然会收到后台通知,但它们不会触发任何构成其外观的代码。

我做了一些挖掘并阅读了一些关于覆盖处理远程通知的方法的内容,但找不到一个很好的例子,甚至找不到要覆盖的具体方法。

这是我的 FirebaseService 类中的 OnMessageReceived 覆盖(忽略看起来不合适的代码。我一直在乱搞东西):

public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        string messageBody = string.Empty;

        if (message.GetNotification() != null)
        {
            switch (message.GetNotification().Title)
            {
                case "Load Matched":
                    break;
            }
            messageBody = message.GetNotification().Body;
        }
        else
        {
            messageBody = message.Data.Values.First();
        }
        try
        {
            MessagingCenter.Send(messageBody, "Update");
        }
        catch (Exception e)
        { 
        }
        SendLocalNotification(messageBody);
    } 

这是我的 SendLocalNotification 方法。我希望远程通知也能触发此方法,以便它们看起来相同。

void SendLocalNotification(string body)
    {
        //Unique request code to avoid PendingIntent collision.
        var requestCode = new Random().Next();

        // accept intent
        var acceptIntent = new Intent(this, typeof(MainActivity));
        acceptIntent.SetAction("ACCEPT_ACTION");
        var pendingIntentAccept = PendingIntent.GetActivity(this, requestCode, acceptIntent, PendingIntentFlags.OneShot);

        // decline intent
        var declineIntent = new Intent(this, typeof(MainActivity));
        declineIntent.SetAction("DECLINE_ACTION");
        var pendingIntentDecline = PendingIntent.GetActivity(this, requestCode, declineIntent, PendingIntentFlags.OneShot);

        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.SingleTop);

        var notificationBuilder = new NotificationCompat.Builder(this)
            .AddAction(0, "Accept", pendingIntentAccept)
            .AddAction(0, "Decline", pendingIntentDecline)

            .SetContentTitle("Content Title")
            .SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
            .SetContentText("content text")
            .SetContentInfo("content info")
            .SetSubText("sub text")
            .SetAutoCancel(true)
            .SetShowWhen(true)
            .SetContentIntent(pendingIntentAccept)
            .SetContentIntent(pendingIntentDecline);

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
        }

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
    }

编辑:这是我用来发送通知的代码。我的印象是,拥有data 标签意味着正在发送数据通知,然后OnMessageReceived 会接收到该通知。

public void SendNotificationByTag(string tag, string notificationBody = "", string notificationTitle = "")
    {
        var url = $"{_baseUrl}/messages/?api-version=2015-01";
        var client = new RestClient($"{url}");
        var request = new RestRequest(Method.POST);
        request.AddHeader("Content-Type", "application/json");
        request.AddHeader("ServiceBusNotification-Format", "gcm");            
        request.AddHeader("ServiceBusNotification-Tags", $"{tag}");
        request.AddHeader("Authorization", $"{NotificationHelper.CreateSasToken(url, "DefaultFullSharedAccessSignature", $"{_configuration["DefaultFullSharedAccessSignature"]}")}");
        request.AddParameter("application/json", $"{{\"data\":\n\t{{\n\t\t\"gcm.notification.body\":\"{notificationBody}\", \n\t\t\"gcm.notification.title\":\"{notificationTitle}\",\n\t}}\n}}", ParameterType.RequestBody);
        client.Execute(request);
    }

【问题讨论】:

    标签: c# android xamarin.forms push-notification firebase-cloud-messaging


    【解决方案1】:

    Firebase 云消息传递支持两个主要的message types

    • 通知消息,有时被认为是“显示消息”。这些由 FCM SDK 自动处理。

    • 数据消息,由客户端应用处理。

    听起来您正在发送通知消息。当您的应用处于非活动状态时,它们会由 OS/SDK 自动处理并显示在系统托盘中,而无需调用您的代码。

    如果您总是希望您的OnMessageReceived 被调用,您应该只发送数据消息。

    另见:How to handle notification when app in background in Firebase

    【讨论】:

    • 我认为有一个数据标签意味着它正在发送数据消息。我用我用来发送通知的代码更新我的帖子。
    • @user1818298 当您的应用在后台或被杀死时,Firebase 不会调用您的 onMessageReceived(),并且您无法自定义通知。它将显示由 Firebase 自行管理的通知。要让 Firebase 库在每种情况下都调用您的 onMessageReceived()。不要将 JSON 密钥“通知”放在您对 Firebase API 的请求中,请改用“数据”,请阅读thisthis
    • @CherryBu-MSFT 我正在使用数据请求。您可以在我的问题中看到我用来发送通知的代码包含请求有效负载正文中的数据键。
    • 感谢您将信息添加到您的问题中。处理属性的方式相当基本,所以我的第一个猜测是notification.title 仍在将其作为通知消息处理。您可能想尝试使用不太可能混淆 SDK 的属性名称,例如 title
    【解决方案2】:

    所以看起来罪魁祸首在请求中有gcm.notification.titlegcm.notification.body。即使它在数据标签内,它看起来仍然作为通知消息传递它。当我用常规的 titlebody 标签替换这两个键时,我开始在应用程序处于后台时点击我的OnMessageReceived

    【讨论】:

      猜你喜欢
      • 2018-08-04
      • 1970-01-01
      • 2020-10-22
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多