Firebase 云消息推送 requireInteraction 不起作用。

4
参考资料:https://github.com/firebase/quickstart-js/tree/master/messaging 我已添加了键值对:
"requireInteraction": true

但是在桌面版Chrome中的通知仍会在20秒后消失。是否有人知道Firebase是否支持该键值对?谢谢!

以下是我的示例。请将[...]更改为您自己的内容。

curl -X POST -H "Authorization: key=[...]" -H "Content-Type: application/json" -d '{
  "notification": {
    "requireInteraction": true,     
    "title": "This is custom title",
    "body": "this is custom body",
    "click_action": "https://google.com",
    "data" : {"requireInteraction": true  }
 },
  "to": "[...]",
}' "https://fcm.googleapis.com/fcm/send"

嗨,塞缪尔。我认为你不应该在负载中设置requireInteraction。它只应在构建通知时声明。如果问题仅涉及支持,则requireInteraction不属于notification负载,但可以存在于data负载中。 :) - AL.
@AL。我已经尝试在数据有效负载或通知有效负载中添加requireInteraction: true,但是在我的Chrome桌面上,通知弹出窗口仍然在20秒后消失。 - Samuel Lui
以下演示中的弹出窗口之一将不会在用户点击之前关闭。 https://googlechrome.github.io/samples/notifications/requireInteraction.html - Samuel Lui
1个回答

9

Firebase在推送消息时会删除notification负载中的requireInteraction属性。有效的解决方法是使用data属性替代notification。然后,您可以使用setBackgroundMessageHandler()方法按照您想要的方式构建通知:

messaging.setBackgroundMessageHandler(function (payload) {
    return self.registration.showNotification(payload.data.title,
        Object.assign({data: payload.data}, payload.data));
});

我已经在上面设置了data,因为这种方法不再使用click_action,你需要自己注册所需的onclick处理程序。下面是一个可行的服务工作线程,它完全符合您设置notification的意图,但使用数据属性代替:

// import scripts omitted 

const messaging = firebase.messaging();
// [END initialize_firebase_in_sw]

self.addEventListener('notificationclick', e => {
    let found = false;
    let f = clients.matchAll({
        includeUncontrolled: true,
        type: 'window'
    })
        .then(function (clientList) {
            for (let i = 0; i < clientList.length; i ++) {
                if (clientList[i].url === e.notification.data.click_action) {
                    // We already have a window to use, focus it.
                    found = true;
                    clientList[i].focus();
                    break;
                }
            }
            if (! found) {
                clients.openWindow(e.notification.data.click_action).then(function (windowClient) {});
            }
        });
    e.notification.close();
    e.waitUntil(f);
});

// [START background_handler]
messaging.setBackgroundMessageHandler(function (payload) {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);
    // Customize notification here

    return self.registration.showNotification(payload.data.title,
        Object.assign({data: payload.data}, payload.data));

});
// [END background_handler]

这是您的curl调用:

curl -X POST -H "Authorization: key=yourKey-" -H "Content-Type: application/json" -d '{
"data": {
    "title": "fooTitle",
    "body": "foo",
    "icon": "image.jpg",
    "click_action": "http://localhost:8000",
    "requireInteraction": true
  },
  "registration_ids": ["id1", "id2"]
}' "https://fcm.googleapis.com/fcm/send"

这还正确吗?我似乎无法使通知持续存在。我正在使用Firebase 4.3.0,上面的curl请求和我的唯一区别是我仍然在其中包含通知负载 - 因此我同时具有数据和通知。 - virtualLast
2
我认为你需要做出决定。如果我没记错的话,通知具有优先权,只有在没有通知有效负载时才会使用数据。 - baao
太棒了,伙计 - 删除了通知部分,它就像魔法般地运行起来了。 - virtualLast
@bambam 这个很完美.. 但是有没有办法让通知在应用程序处于焦点状态时也能显示出来? - Tallboy
@bambam:用户清除缓存后如何获取新的令牌?还有任何想法可以获取唯一的浏览器ID以保存令牌,以避免令牌重复。谢谢。 - Keyur Thumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接