Android 当应用程序位于后台时,FCM意图在哪里交付数据?

Android 当应用程序位于后台时,FCM意图在哪里交付数据?,android,firebase,push-notification,firebase-cloud-messaging,android-push-notification,Android,Firebase,Push Notification,Firebase Cloud Messaging,Android Push Notification,我已经在我的应用程序中实现了Firebase,我正在发送带有额外数据的推送。当我的应用程序在前台时,我会正确处理数据并显示我自己的通知,但当Firebase在应用程序被“托管”(未终止)时“自动”显示通知时,我在获取数据方面有问题。根据活动应获得新的意图,并用我的值实现额外功能,而不是应用程序返回前端,恢复旧状态 情景: 打开应用程序,按Home 通过Firebase控制台发送推送,Firebase正在创建通知,而没有调用onMessageReceived(根据文档中的表格,应该是吗?) 当用户

我已经在我的应用程序中实现了Firebase,我正在发送带有额外数据的推送。当我的应用程序在前台时,我会正确处理数据并显示我自己的通知,但当Firebase在应用程序被“托管”(未终止)时“自动”显示通知时,我在获取数据方面有问题。根据
活动
应获得新的
意图
,并用我的值实现额外功能,而不是应用程序返回前端,恢复旧状态

情景:

  • 打开应用程序,按Home
  • 通过Firebase控制台发送推送,Firebase正在创建
    通知
    ,而没有调用
    onMessageReceived
    (根据文档中的表格,应该是吗?)
  • 当用户选择通知应用程序将以与“主页”相同的状态被带到前台时,
    Intent
    将通过顶部用于打开
    活动的“原始”附加功能来实现
  • 我在
    onCreate
    onNewIntent
    onResume
    Activity
    )和
    onMessageReceived
    Service
    )中都有日志,只调用了
    onResume
    ,其中我打印了如下额外内容:

    if (getIntent().getExtras() != null) {
            for (String key : getIntent().getExtras().keySet()) {
                Object value = getIntent().getExtras().get(key);
                Log.d("Activity onResume", "Key: " + key + " Value: " + value);
            }
        }
    

    根据文件规定,信息可分为三种状态:

  • 通知
  • 资料
  • 通知和数据
  • 后台处理:

    两个人<将调用code>onMessageReceived
    ,而无需UI和其他处理。稍后您可以显示自定义的内容

    说到3。android将显示通知并保留数据,直到用户交互。单击后,它只是恢复您现有的活动。您的
    onNewIntent
    未被触发,因为您的启动模式不是
    FLAG\u ACTIVITY\u SINGLE\u TOP

    您还应该检查您的logcat输出:
    Google Play services过期

    onMessageReceived()在应用程序处于后台时未被调用。几个月前我有这个问题。我通过override handlerIntent方法解决了这个问题。但是您的firebase消息传递库应该

    implementation 'com.google.firebase:firebase-messaging:10.2.1'
    
    之后:

    @Override
        public void handleIntent(Intent intent) {
            try
            {
                if (intent.getExtras() != null)
                {
                    RemoteMessage.Builder builder = new RemoteMessage.Builder("MessagingService");
    
                    for (String key : intent.getExtras().keySet())
                    {
                        builder.addData(key, intent.getExtras().get(key).toString());
                    }
    
                    onMessageReceived(builder.build());
                }
                else
                {
                    super.handleIntent(intent);
                }
            }
            catch (Exception e)
            {
                super.handleIntent(intent);
            }
        }
    
    如果您不想降级库,那么

    您可以指定单击操作,以指示用户点击通知时应启动的意图。如果未指定单击操作,则使用主活动

    启动意图后,您可以使用

    getIntent().getExtras();
    
    检索包含随通知消息一起发送的任何数据的集合


    有关通知消息的更多信息,请参阅带有通知和数据负载(包括后台和前台)的消息。在这种情况下,数据有效载荷被交付到您的启动器活动的目的之外。如果您想在其他活动中使用它,则必须在数据有效负载上定义click_操作。因此,在你的启动器活动中获得额外的意图

    编辑:-

    从:- 在后台时,应用程序在通知托盘中接收通知负载,并且仅在用户点击通知时处理数据负载


    因此,在单击通知时,使用getIntent()额外功能检查启动器活动的oncreate()方法。

    因此我一直在寻找这个答案,并阅读了相同的内容。一定是在什么地方。 我知道这已经是一年前的事了,但他们还没有说清楚。 在与通知关联的pendingActivity中(在我的示例中,它是MainActivity) 我补充了以下内容。 请注意,我是通过Google Codelabs com.example.android.eggtimernotifications工作的,而不是在答案中

        override fun onResume() {
            super.onResume()
            intent?.run {
                val keys = this.extras?.keySet()
                if (!keys.isNullOrEmpty()) {
                    keys.forEach { key ->
                        when (this.extras!![key]) {
                            is Long -> println("$key = ${this.getLongExtra(key, 0L)}")
                            is Int -> println("$key = ${this.getIntExtra(key, 0)}")
                            is String -> println("$key = ${this.getStringExtra(key)}")
                            is Boolean -> println("$key = ${this.getBooleanExtra(key, false)}")
                            else -> println("unkonwn Type")
                        }
                    }
                }
            }
        }
    
    这导致了以下情况

    • I/System.out:google.delivered\u优先级=高
    • I/System.out:google.sent_time=15852849414411
    • I/System.out:google.ttl=2419200
    • I/System.out:google.original\u优先级=高
    • I/System.out:谷物=碎纸
    • I/System.out:from=/topics/早餐
    • I/System.out:牛奶=1杯
    • I/System.out:糖=无
    • I/System.out:google.message_id=0:15852849414700957%f6ddf818f6ddf818
    • I/System.out:collapse\u key=com.example.android.eggtimernotifications

    数据键为谷物、from、牛奶和糖。

    使用Firebase控制台,我只能发送通知或通知与数据推送。我必须使用第二个自定义参数。当应用程序被“托管”,在后台仍然处于活动状态时,
    onMessageReceived
    根本不会被调用(无论是在接收推送时还是在按下通知时)@snachmsm无法从控制台发送仅数据的消息。从文档:
    在受信任的环境(如云功能或应用服务器)中,使用Admin SDK或FCM服务器协议:仅设置数据密钥这不是真的,发送推送表单的最后一部分“高级设置”(或选项,我有本地化的控制台)允许您添加自定义键值参数。当应用程序处于前台或被关闭时,我可以毫无问题地获取它们。Console允许您发送文本和可选数据。但您不能从控制台发送仅数据的消息。这就是区别。这是真的,但这并不能解决我的问题。。。我需要额外的数据,所以我必须自己处理自动显示
    通知
    ,它携带我的字段。问题是我无法在上述场景中获取我的键值对……当前Firebase版本是17(我使用的是17.1++),我不会降级这个库,特别是这么多,所以它不是一个解决方案。在当前版本中,我们无法覆盖
    handleIntent
    我知道很少有人不愿意降级库,这就是为什么我已经提到最新版本的解决方案,如果我的应用程序被终止,那么数据将被发送到launchers活动,这是真的。我所说的情况是,当应用程序已经打开,然后它在最后一个
    活动
    返回到前面,并且launcher
    活动
    未被调用/OpenedFreebase将调用launcher Activity getI