简体   繁体   English

创建本地通知以响应cordova / ionic中的推送通知(来自firebase)

[英]Creating a local notification in response to a push notification (from firebase) in cordova/ionic

I'm building an application using Ionic Framework that implements a chat function similar to good-old facebook messenger, in that i want to notify users of a chat message, but if they view it elsewhere, i want to remove the notification from their home screen. 我正在使用Ionic Framework构建一个应用程序,它实现类似于好老的facebook messenger的聊天功能,因为我想通知用户聊天消息,但如果他们在其他地方查看,我想从他们的家中删除通知屏幕。

I'm using firebase as a back-end for push notifications (though that could be changed i suppose). 我正在使用firebase作为推送通知的后端(尽管我可以改变它)。

I know that you can't expire a remote notification, but i've been told you can expire + remove a local notification, so my question is - can i reliably receive a remote notification, create a local one, and display that, and then in response to a notification with a scope of 'expire' or 'remove', delete a local notification so that my users don't see a duplication of information? 我知道你不能过期远程通知,但我被告知你可以过期+删除本地通知,所以我的问题是 - 我能否可靠地接收远程通知,创建本地通知,并显示,以及然后,为了响应范围为“过期”或“删除”的通知,删除本地通知,以便我的用户看不到重复的信息?

Most plugins tend to detect the status of the app and add a remote notification to the homescreen with the info you've pushed by default, is there a way to avoid this? 大多数插件倾向于检测应用程序的状态,并使用您默认推送的信息向主屏幕添加远程通知,有没有办法避免这种情况?

Thanks guys. 多谢你们。

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

As far as I can tell there're no plugins which accomplish all what you need. 据我所知,没有任何插件可以满足您的所有需求。 However.. 然而..

can i reliably receive a remote notification, create a local one, and display that, and then in response to a notification with a scope of 'expire' or 'remove', delete a local notification so that my users don't see a duplication of information? 我能否可靠地接收远程通知,创建本地远程通知并显示该通知,然后在响应“过期”或“删除”范围的通知时删除本地通知,以便我的用户看不到重复信息?

Most plugins tend to detect the status of the app and add a remote notification to the homescreen with the info you've pushed by default, is there a way to avoid this? 大多数插件倾向于检测应用程序的状态,并使用您默认推送的信息向主屏幕添加远程通知,有没有办法避免这种情况?

Yes, by using silent notifications and building the local notification by yourself. 是的,通过使用静默通知并自行构建本地通知。

For a project I'm working in, I modified the plugin cordova-plugin-fcm to add support for (local on demand) notifications dismiss/display, send multiple notifications to the cordova app, and some PRs that are not included yet. 对于我正在工作的项目,我修改了插件cordova-plugin-fcm以添加支持(本地点播)通知解除/显示,向cordova app发送多个通知,以及一些尚未包含的PR。 Also I build the notification by myself, to have full control of what is displayed. 此外,我自己构建通知,以完全控制显示的内容。 You can take a look at the code to get some ideas. 您可以查看代码以获得一些想法。

In brief it works like this: 简而言之,它的工作原理如下:

Firstly, I send a "silent" push to the app, which is not displayed by Android: 首先,我发送一个“静音”推送到应用程序,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"
    }
}

Note: If the payload have the "notification": {} item, Android will display it on the system tray (if the app is in background). 注意:如果有效负载具有"notification": {}项,Android将在系统托盘上显示它(如果应用程序在后台)。 https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

Secondly, when the push arrives to the app (in onMessageReceived() ), I build the local notification, assigning it a TAG and an ID. 其次,当推送到应用程序时(在onMessageReceived()中 ),我构建本地通知,为其分配TAG和ID。 This is the way you can use to dismiss it later. 这是您以后可以用来解散它的方法。 For example, you could create a local notification with the TAG "NEW_USER_MESSAGE" and ID 1 (a constant indicating a state of the message, or the user ID for example). 例如,您可以使用TAG“NEW_USER_MESSAGE”和ID 1(表示消息状态的常量或例如用户ID)创建本地通知。 Also, Android will replace notifications with the same TAG and ID , so this is another way to automatically replace notifications (for example if you send a generic message, like "New update available"). 此外, Android将使用相同的TAG和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);

One advantage of doing it in this way, is that you have full control of the notification to be displayed, so you can stylize it like you want. 以这种方式执行此操作的一个优点是,您可以完全控制要显示的通知,因此您可以根据需要对其进行样式化。

If you want to discard expired messages, you can 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");

Thirdly, when the user clicks on a notification Android will launch your app, and the plugin will send the payload of the push message to the cordova view ( onNotificationReceived() ). 第三,当用户点击通知时,Android将启动您的应用程序,插件会将推送消息的有效负载发送到cordova视图( onNotificationReceived() )。

Once your app is opened and you have received the push message, you can dismiss it adding a new action to the plugin: 一旦您的应用程序打开并且您收到了推送消息,您可以忽略它向插件添加新操作:

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

The Android action: 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 https://github.com/TrustedCircles/cordova-plugin-fcm/blob/master/src/android/FCMPlugin.java#L286

And the method exposed to the cordova app: 并且该方法暴露给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 https://github.com/TrustedCircles/cordova-plugin-fcm/blob/master/www/FCMPlugin.js#L65

The only tricky bit with notifications in cordova/ionic is the JS part receiving the notification and triggering the Android code. 在cordova / ionic中通知的唯一棘手的部分是JS部分接收通知并触发Android代码。

I used https://github.com/phonegap/phonegap-plugin-push library and its pretty straight forward. 我使用https://github.com/phonegap/phonegap-plugin-push库,非常简单。

There is a callback when notifications are received in JS(Cordova/Ionic), use this to render you notifications locally in Android. 在JS(Cordova / Ionic)中收到通知时会有回调,使用它在Android中本地呈现通知。

PS: Basel's answer tells you how to clear your notifications, so I decided to leave that bit out. PS:巴塞尔的回答告诉你如何清除你的通知,所以我决定把这一点留下来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM