【问题标题】:Creating a local notification in response to a push notification (from firebase) in cordova/ionic在cordova / ionic中创建本地通知以响应推送通知(来自firebase)
【发布时间】:2018-01-06 11:00:05
【问题描述】:

我正在使用 Ionic Framework 构建一个应用程序,该应用程序实现了类似于老式 facebook messenger 的聊天功能,因为我想通知用户聊天消息,但如果他们在其他地方查看它,我想删除通知从他们的主屏幕。

我使用 firebase 作为推送通知的后端(尽管我想这可能会改变)。

我知道远程通知不能过期,但有人告诉我你可以过期 + 删除本地通知,所以我的问题是 - 我能否可靠地接收远程通知,创建一个本地通知,并显示它,然后响应范围为“过期”或“删除”的通知,删除本地通知,以便我的用户不会看到重复的信息?

大多数插件倾向于检测应用程序的状态,并使用您默认推送的信息向主屏幕添加远程通知,有没有办法避免这种情况?

谢谢大家。

编辑: - 本地通知:http://ionicframework.com/docs/native/local-notifications/ - Firebase 云消息:https://github.com/fechanique/cordova-plugin-fcm

【问题讨论】:

  • 如何将远程通知转换为本地通知?

标签: android ios cordova ionic-framework


【解决方案1】:

据我所知,没有插件可以满足您的所有需求。不过..

我能否可靠地接收远程通知,创建本地通知并显示它,然后响应范围为“过期”或“删除”的通知,删除本地通知,以便我的用户不会看到重复的信息?

大多数插件倾向于检测应用程序的状态,并使用您默认推送的信息向主屏幕添加远程通知,有没有办法避免这种情况?

是的,通过使用silent notifications 并自己构建本地通知。

对于我正在从事的项目,我修改了插件cordova-plugin-fcm 以添加对(本地按需)通知关闭/显示的支持,向cordova 应用程序发送多个通知,以及一些尚未包含的 PR。此外,我自己构建通知,以完全控制显示的内容。您可以查看代码以获得一些想法。

简而言之,它的工作原理如下:

首先,我向应用程序发送“静默”推送,Android 不显示:

{
    "content_available": true, // IMPORTANT: For Apple -> content-available: 1, for firebase -> content_available: true
    "priority": "high",
    "to": "/topics/all", // or to a fcm token
    "data"{
        "title": "My title", // this implies that you display the notification by yourself
        "body": "My body", // this implies that you display the notification by yourself
        "type": "NEW_USER_MESSAGE", // only relevant to this project
        "userId": "1", // only relevant to this project
        "timestamp", "150000000"
    }
}

注意:如果有效负载有"notification": {} 项,Android 将在系统托盘上显示它(如果应用程序在后台)。 https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

其次,当推送到达应用程序时(onMessageReceived()),我构建本地通知,为其分配一个 TAG 和一个 ID。这是您以后可以用来关闭它的方式。 例如,您可以使用标签“NEW_USER_MESSAGE”和 ID 1(指示消息状态的常量,或例如用户 ID)创建本地通知。另外,Android will replace notifications with the same TAG and ID,因此这是自动替换通知的另一种方式(例如,如果您发送通用消息,例如“有新更新可用”)。

    public static String TYPE_NEW_USER_MESSAGE = "NEW_USER_MESSAGE";
    public static String TYPE_USER_LEFT_ROOM = "USER_LEFT_ROOM";

    NotificationManager notificationManager =
            (NotificationManager) _ctx.getSystemService(Context.NOTIFICATION_SERVICE);

    // based in the type of the message you've received, you can stylize the notification
    if (type.equals( TYPE_USER_LEFT_ROOM )){
        notificationBuilder.setColor(Color.RED);
        notificationBuilder.setLights(Color.RED, 1000, 500);
    }
    else if (type.equals( TYPE_NEW_USER_MESSAGE )){
        notificationBuilder.setColor(Color.BLUE);
        notificationBuilder.setLights(Color.BLUE, 1000, 1000);
    }

    Notification n = notificationBuilder.build();
    notificationManager.notify(type, userId, n);

这样做的一个好处是,您可以完全控制要显示的通知,因此您可以随意设置它的样式。

如果你想丢弃过期消息,可以check out the elapsed time between the sent timestamp and the current timestamp

java.util.Date now = new java.util.Date();
java.util.Date sent_timestamp = new java.util.Date( Long.valueOf(timestamp.toString()) );
            final Long elapsed_time = ((now.getTime() - sent_timestamp.getTime()) / 1000);
Log.d(TAG, "New message. sent " + elapsed_time + "s ago");

第三,当用户点击通知时,Android 将启动您的应用,插件会将推送消息的有效负载发送到 cordova 视图 (onNotificationReceived())。

打开您的应用并收到推送消息后,您可以将其关闭,向插件添加新操作:

onNotificationReceived(data){
    if (data.wasTapped === true){
        if (data.type === 'NEW_USER_MESSAGE'){
            FCMPlugin.dismissNotification(NEW_USER_MESSAGE, 1);
        }
    }
}

Android 动作:

else if (action.equals( ACTION_DISMISS_NOTIFICATION )) {
    cordova.getThreadPool().execute(new Runnable() {
        public void run() {
            try{
                Log.d(TAG, "FCMPlugin dismissNotificaton: " + args.getString(0)); //tag
                NotificationManager nManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
                        nManager.cancel(args.getString(0)/*NEW_USER_MESSAGE*/, args.getInt(1) /*1*/);
                Log.d(TAG, "FCMPlugin dismissNotificaton() to remove: " + id); //tag
                callbackContext.success();
            }catch(Exception e){
                callbackContext.error(e.getMessage());
            }
       }
 });

https://github.com/TrustedCircles/cordova-plugin-fcm/blob/master/src/android/FCMPlugin.java#L286

以及暴露给cordova app的方法:

// dismisses a notification by tag+id
FCMPlugin.prototype.dismissNotification = function( tag, userId, success, error ){
    exec(success, error, "FCMPlugin", 'dismissNotification', [tag, userId]);
}

https://github.com/TrustedCircles/cordova-plugin-fcm/blob/master/www/FCMPlugin.js#L65

【讨论】:

  • 您的答案似乎非常完整,但据我所知,它没有发现在没有运行应用程序的情况下接收通知的能力,对吗?只是为了确认。谢谢
【解决方案2】:

cordova/ionic 中通知的唯一棘手之处是 JS 部分接收通知并触发 Android 代码。

我使用了https://github.com/phonegap/phonegap-plugin-push 库,它非常简单。

在 JS(Cordova/Ionic) 中收到通知时有一个回调,使用它在 Android 本地呈现通知。

P.S:巴塞尔的回答告诉你如何清除通知,所以我决定把那一点省略。

【讨论】:

    猜你喜欢
    • 2017-01-27
    • 1970-01-01
    • 2018-12-25
    • 2019-06-27
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多