在 Firebase FCM 上检测前景推送点击事件
Detect Foreground push click event on Firebase FCM
我在 Ionic 4 应用程序中使用 firebase 插件。当用户单击前台推送时,我有一个用例要实现。即他必须重定向到不同的 UI。我怎样才能做到这一点?我可以使用后台推送点击用例来做到这一点。
fcmListeners() {
this.firebase.onNotificationOpen().subscribe(async (data: any) => {
if (data.tap) {// when user tapped the background notification
this.pushRedirection(data);
console.log("Received in background-data", data);
} else {
console.log("Received in foreground", data);
this.pushRedirection(data);
}
});
}
如果我使用上述代码,它会自动转到所需的页面,而无需用户单击。但是如果用户只点击推送,我需要实现它。那么你能告诉我如何处理吗?
有效负载:
{
"registration_ids": [
"dlaNHzi7Gy8:APA91bGdn_jXFJm1xdGGI44s48JbXEu5iYa"
],
"notification": {
"body": "Push Test Facility Category",
"title": null,
"icon": "myicon",
"sound": "mySound",
"vibrate": 1,
"Badge": 1,
"click_action": "FCM_PLUGIN_ACTIVITY"
},
"data": {
"message": "Push Test Facility Category",
"title": null,
"b": "22",
"id": "2",
"category_name": "Restaurants",
"h": "1",
"p": 1,
"type": "2"
}
}
this.firebase.onNotificationOpen().subscribe(async (data: any)
注意: 我可以在此处为 android 实现自定义通知 toast,因为它不会在前台通知中显示任何内容。但是 iOS 它默认显示前台通知。那怎么处理呢?
Firebase Corodva 插件当前显示推送通知,即使接收到的通知是前台的应用程序,但那是 an issue,不应该是默认行为。正如您在该问题中看到的那样,在修复合并之前,您可以像这样在本地修复它:
I changed
PROJECT_ROOT/plugins/cordova-plugin-firebase/src/ios/AppDelegate+FirebasePlugin.m
but also
PROJECT_ROOT/platforms/ios/PROJECT_NAME/plugins/cordova-plugin-firebase/AppDelegate+FirebasePlugin.m
In both files in line 183, I replaced
completionHandler(UNNotificationPresentationOptionAlert);
with
completionHandler(UNNotificationPresentationOptionNone);
Now, it behaves like expected (no notification in foreground, only in
background)
修复后,您可以使用 data.tap
并且应该可以正常工作:
if (data.tap) {
// when user tapped the background notification
this.pushRedirection(data);
console.log("Received in background-data", data);
}
如果您需要在 CI/CD 环境中执行此操作,或者您只想将其自动化,您可以创建一个 Cordova Hook.
为此,首先在 src
中创建一个新的 cordova-hooks
文件夹,然后创建一个名为 fix_push-notifications-foreground_issue.js
的新 js 文件,如下所示:
src
|- ...
|- cordova-hooks
|- fix_push-notifications-foreground_issue.js
|- node_modules
|- ...
请注意,还有一些其他方法可以添加 Cordova 挂钩(例如使用默认的 hooks
文件夹),但我仍然更喜欢使用自定义文件夹。可以找到更多信息 here.
将以下代码粘贴到新的 js 文件中:
#!/usr/bin/env node
module.exports = function (context) {
const fs = require('fs');
const path = require('path');
const issue = `completionHandler(UNNotificationPresentationOptionAlert);`;
const fix = `completionHandler(UNNotificationPresentationOptionNone);`;
// ISSUE: iOS: Push notifications are shown when in foreground
// https://github.com/arnesson/cordova-plugin-firebase/issues/817
function start() {
console.log('+------------------------------------+');
console.log('| Starting PN Foreground Fix Hook |');
console.log('+------------------------------------+');
const pluginDir = path.join(context.opts.projectRoot, '/plugins/cordova-plugin-firebase-lib/src/ios');
const pluginFile = path.join(pluginDir, 'AppDelegate+FirebasePlugin.m');
const platformPluginDir = path.join(context.opts.projectRoot, '/platforms/ios/YourAppName/Plugins/cordova-plugin-firebase-lib');
const platformPluginFile = path.join(platformPluginDir, 'AppDelegate+FirebasePlugin.m');
applyFixToFile(pluginFile);
applyFixToFile(platformPluginFile);
console.log('+------------------------------------+');
}
/**
* Fixes the push notification foreground issue on the file sent as parametner
* @param {*} file Path of the file to be fixed
*/
function applyFixToFile(file) {
if (fs.existsSync(file)) {
let content = fs.readFileSync(file).toString('utf8');
if (content.indexOf(issue) > -1) {
content = content.replace(issue, fix);
fs.writeFileSync(file, content);
console.log(` PN foregorund fix applied to ${file} file`);
} else {
console.log(` No need to apply PN foreground fix to ${file} file`);
}
} else {
console.log(` Unable to find ${file} file`);
}
}
// Start the hook
start();
}
最后,在您的 config.xml
文件中添加挂钩:
<widget ...
<hook src="cordova-hooks/fix_push-notifications-foreground_issue.js" type="before_prepare" />
<platform name="android">
...
</platform>
<platform name="ios">
...
</platform>
</widget>
现在每次构建应用程序时,都会自动应用修复:)
我在 Ionic 4 应用程序中使用 firebase 插件。当用户单击前台推送时,我有一个用例要实现。即他必须重定向到不同的 UI。我怎样才能做到这一点?我可以使用后台推送点击用例来做到这一点。
fcmListeners() {
this.firebase.onNotificationOpen().subscribe(async (data: any) => {
if (data.tap) {// when user tapped the background notification
this.pushRedirection(data);
console.log("Received in background-data", data);
} else {
console.log("Received in foreground", data);
this.pushRedirection(data);
}
});
}
如果我使用上述代码,它会自动转到所需的页面,而无需用户单击。但是如果用户只点击推送,我需要实现它。那么你能告诉我如何处理吗?
有效负载:
{
"registration_ids": [
"dlaNHzi7Gy8:APA91bGdn_jXFJm1xdGGI44s48JbXEu5iYa"
],
"notification": {
"body": "Push Test Facility Category",
"title": null,
"icon": "myicon",
"sound": "mySound",
"vibrate": 1,
"Badge": 1,
"click_action": "FCM_PLUGIN_ACTIVITY"
},
"data": {
"message": "Push Test Facility Category",
"title": null,
"b": "22",
"id": "2",
"category_name": "Restaurants",
"h": "1",
"p": 1,
"type": "2"
}
}
this.firebase.onNotificationOpen().subscribe(async (data: any)
注意: 我可以在此处为 android 实现自定义通知 toast,因为它不会在前台通知中显示任何内容。但是 iOS 它默认显示前台通知。那怎么处理呢?
Firebase Corodva 插件当前显示推送通知,即使接收到的通知是前台的应用程序,但那是 an issue,不应该是默认行为。正如您在该问题中看到的那样,在修复合并之前,您可以像这样在本地修复它:
I changed
PROJECT_ROOT/plugins/cordova-plugin-firebase/src/ios/AppDelegate+FirebasePlugin.m
but also
PROJECT_ROOT/platforms/ios/PROJECT_NAME/plugins/cordova-plugin-firebase/AppDelegate+FirebasePlugin.m
In both files in line 183, I replaced
completionHandler(UNNotificationPresentationOptionAlert);
with
completionHandler(UNNotificationPresentationOptionNone);
Now, it behaves like expected (no notification in foreground, only in background)
修复后,您可以使用 data.tap
并且应该可以正常工作:
if (data.tap) {
// when user tapped the background notification
this.pushRedirection(data);
console.log("Received in background-data", data);
}
如果您需要在 CI/CD 环境中执行此操作,或者您只想将其自动化,您可以创建一个 Cordova Hook.
为此,首先在 src
中创建一个新的 cordova-hooks
文件夹,然后创建一个名为 fix_push-notifications-foreground_issue.js
的新 js 文件,如下所示:
src
|- ...
|- cordova-hooks
|- fix_push-notifications-foreground_issue.js
|- node_modules
|- ...
请注意,还有一些其他方法可以添加 Cordova 挂钩(例如使用默认的 hooks
文件夹),但我仍然更喜欢使用自定义文件夹。可以找到更多信息 here.
将以下代码粘贴到新的 js 文件中:
#!/usr/bin/env node
module.exports = function (context) {
const fs = require('fs');
const path = require('path');
const issue = `completionHandler(UNNotificationPresentationOptionAlert);`;
const fix = `completionHandler(UNNotificationPresentationOptionNone);`;
// ISSUE: iOS: Push notifications are shown when in foreground
// https://github.com/arnesson/cordova-plugin-firebase/issues/817
function start() {
console.log('+------------------------------------+');
console.log('| Starting PN Foreground Fix Hook |');
console.log('+------------------------------------+');
const pluginDir = path.join(context.opts.projectRoot, '/plugins/cordova-plugin-firebase-lib/src/ios');
const pluginFile = path.join(pluginDir, 'AppDelegate+FirebasePlugin.m');
const platformPluginDir = path.join(context.opts.projectRoot, '/platforms/ios/YourAppName/Plugins/cordova-plugin-firebase-lib');
const platformPluginFile = path.join(platformPluginDir, 'AppDelegate+FirebasePlugin.m');
applyFixToFile(pluginFile);
applyFixToFile(platformPluginFile);
console.log('+------------------------------------+');
}
/**
* Fixes the push notification foreground issue on the file sent as parametner
* @param {*} file Path of the file to be fixed
*/
function applyFixToFile(file) {
if (fs.existsSync(file)) {
let content = fs.readFileSync(file).toString('utf8');
if (content.indexOf(issue) > -1) {
content = content.replace(issue, fix);
fs.writeFileSync(file, content);
console.log(` PN foregorund fix applied to ${file} file`);
} else {
console.log(` No need to apply PN foreground fix to ${file} file`);
}
} else {
console.log(` Unable to find ${file} file`);
}
}
// Start the hook
start();
}
最后,在您的 config.xml
文件中添加挂钩:
<widget ...
<hook src="cordova-hooks/fix_push-notifications-foreground_issue.js" type="before_prepare" />
<platform name="android">
...
</platform>
<platform name="ios">
...
</platform>
</widget>
现在每次构建应用程序时,都会自动应用修复:)