当应用程序处于后台时,FCM Intent 与数据交付在哪里?

Where is FCM Intent with data delivered, when app is in background?

我已经在我的应用程序中实施了 Firebase,并且正在发送带有额外数据的推送。当我的应用程序处于前台时,我正在正确处理数据并显示我自己的通知,但是当 Firebase 显示 Notification "automatically" 当应用程序 "homed" (未被杀死)时,我在获取数据时遇到了问题。根据 DOCS Activity 应该得到新的 Intent 并且额外的东西符合我的价值观,而不是应用程序只是回到前面,旧状态被恢复。

场景:

  1. 正在打开应用,按主页
  2. 通过 Firebase 控制台发送推送,Firebase 正在创建 Notification 而不调用 onMessageReceived(根据文档中的 table,它应该?)
  3. 当用户选择通知应用程序将以与 "homed" 相同的状态置于最前面时,并且 Intent 满足 "original" 用于打开 Activity 的额外内容顶部

我登录了 onCreateonNewIntentonResume (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);
        }
    }

根据文档Cloud messaging docs消息可以在 3 种状态下传递:

  1. 通知
  2. 数据
  3. 通知和数据

后台处理:

对于 2。将在没有 UI 和额外处理的情况下调用 onMessageReceived。稍后你可以展示一些定制的东西。

当涉及到 3 时。android 将显示通知并保留数据,直到有用户交互。单击后它只是恢复您现有的 activity。您的 onNewIntent 未触发,因为您的启动模式不是 FLAG_ACTIVITY_SINGLE_TOP

您还应该检查您的 logcat 输出:Google Play services out of date.

当应用程序处于后台时,不会调用 onMessageReceived()。几个月前我遇到了这个问题。我通过覆盖 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);
        }
    }

如果您不想降级您的图书馆,那么

您可以指定一个 click_action 来指示当用户点击通知时应启动的意图。如果没有指定 click_action,则使用主 activity。

启动 Intent 后,您可以使用

getIntent().getExtras();

检索包含随通知消息一起发送的任何数据的集合。

有关通知消息的更多信息,请参阅 https://firebase.google.com/docs/cloud-messaging/android/receive#sample-receive

具有通知和数据负载的消息,包括背景和前景。在这种情况下,数据有效载荷被传送到启动器意图的额外部分 activity。如果你想在其他activity上获取它,你必须在数据负载上定义click_action。所以在你的启动器中获得额外的意图 activity.

编辑:-

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

所以在点击通知时检查启动器 activity 的 oncreate() 方法和 getIntent() extras。

所以我一直在寻找这个答案并阅读相同的内容。它必须在某个地方。 我知道这是一岁了,但他们还没有真正说清楚。 在与通知关联的 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.输出:google.delivered_priority = 高
  • I/System.out: google.sent_time = 1585284914411
  • I/System.out: google.ttl = 2419200
  • I/System.输出:google.original_priority = 高
  • I/System.out: 麦片 = Shreddies
  • I/System.out: 来自=/topics/breakfast
  • I/System.out: 牛奶 = 1 杯
  • I/System.out: sugar = none
  • I/System.out: google.message_id = 0:1585284914700957%f6ddf818f6ddf818
  • I/System.out: collapse_key = com.example.android.eggtimernotifications

数据键是谷物、牛奶和糖。