如何在 flutter 中按 device/user 禁用云消息传递?
How to disable cloud messaging per device/user in flutter?
对于 flutter 应用程序,我使用 Firebase 云消息传递和云功能向用户发送推送通知,使用他们的 FCM 注册令牌。该应用程序有一个设置页面,用户应该可以在其中关闭某些推送通知。通知是特定于用户的,因此订阅或取消订阅的主题将不起作用,但通知可以分类为特定类别。
例如,在聊天应用程序中,当用户 A 向用户 B 发送消息时,推送通知可能属于“聊天消息”类别,而用户 A 也可以删除与用户 B 的聊天,并且该推送通知可以属于“已删除的聊天记录”类别。
我怎样才能让用户 B 可以关闭“已删除聊天”的通知,同时仍然收到“聊天消息”的通知?是否可以以一种或另一种方式使用带有主题和用户注册令牌的条件?非常感谢任何想法!
多亏了 Doug 在正确方向上的大力推动,我才能够弄明白!在下面发布我的代码,以帮助任何人朝着正确的方向迈出相同的一步。
因此,在我的 flutter 应用程序的设置页面中,用户可以打开和关闭几个类别的通知。然后,用户的偏好存储在我的 Cloud Firestore users
集合中的用户特定文档中。有关我在设置页面上使用的 SwitchListTile
的示例,请参见下面的代码。
SwitchListTile(
title: Text('Admin notifications'),
subtitle: Text('Maintenance and general notes'),
onChanged: (value) {
setState(() {
adminNotifications = value;
Firestore.instance
.collection('users')
.document(loggedInUser.uid)
.updateData({
'adminNotifications': value,
});
});
save('adminNotifications', value);
},
value: adminNotifications,
),
在我的云函数中,我添加了对 users
集合中文档的引用,并检查字段 adminNotifications
的值是否等于 true
。如果是,则发送通知,否则不向用户发送通知。下面我添加了云功能。请注意,云函数会呈现 'nested promises' 警告,但它现在有效!我仍然是 Flutter 初学者,所以我很高兴它能正常工作。再次感谢道格!
exports.userNotifications = functions.firestore.document('notifications/{any}').onCreate((change, context) => {
const userFcm = change.data().fcmToken;
const title = change.data().title;
const body = change.data().body;
const forUser = change.data().for;
const notificationContent = {
notification: {
title: title,
body: body,
badge: '1',
click_action: 'FLUTTER_NOTIFICATION_CLICK',
}
};
var usersRef = db.collection('users');
var queryRef = usersRef.where('login', '==', forUser).limit(1).get()
.then(snapshot => {
snapshot.forEach(doc => {
const adminNotifications = doc.data().adminNotifications;
console.log(adminNotifications);
if(swapNotifications === true){
return admin.messaging().sendToDevice(userFcm, notificationContent)
.then(() => {
console.log('notification sent')
return
})
.catch(error =>{
console.log('error in sending notification', error)
})
} else {
console.log('message not send due to swapNotification preferences')
}
return console.log('reading user data success');
})
.catch(err => {
console.log('error in retrieving user data:', err)
})
});
对于 flutter 应用程序,我使用 Firebase 云消息传递和云功能向用户发送推送通知,使用他们的 FCM 注册令牌。该应用程序有一个设置页面,用户应该可以在其中关闭某些推送通知。通知是特定于用户的,因此订阅或取消订阅的主题将不起作用,但通知可以分类为特定类别。
例如,在聊天应用程序中,当用户 A 向用户 B 发送消息时,推送通知可能属于“聊天消息”类别,而用户 A 也可以删除与用户 B 的聊天,并且该推送通知可以属于“已删除的聊天记录”类别。
我怎样才能让用户 B 可以关闭“已删除聊天”的通知,同时仍然收到“聊天消息”的通知?是否可以以一种或另一种方式使用带有主题和用户注册令牌的条件?非常感谢任何想法!
多亏了 Doug 在正确方向上的大力推动,我才能够弄明白!在下面发布我的代码,以帮助任何人朝着正确的方向迈出相同的一步。
因此,在我的 flutter 应用程序的设置页面中,用户可以打开和关闭几个类别的通知。然后,用户的偏好存储在我的 Cloud Firestore users
集合中的用户特定文档中。有关我在设置页面上使用的 SwitchListTile
的示例,请参见下面的代码。
SwitchListTile(
title: Text('Admin notifications'),
subtitle: Text('Maintenance and general notes'),
onChanged: (value) {
setState(() {
adminNotifications = value;
Firestore.instance
.collection('users')
.document(loggedInUser.uid)
.updateData({
'adminNotifications': value,
});
});
save('adminNotifications', value);
},
value: adminNotifications,
),
在我的云函数中,我添加了对 users
集合中文档的引用,并检查字段 adminNotifications
的值是否等于 true
。如果是,则发送通知,否则不向用户发送通知。下面我添加了云功能。请注意,云函数会呈现 'nested promises' 警告,但它现在有效!我仍然是 Flutter 初学者,所以我很高兴它能正常工作。再次感谢道格!
exports.userNotifications = functions.firestore.document('notifications/{any}').onCreate((change, context) => {
const userFcm = change.data().fcmToken;
const title = change.data().title;
const body = change.data().body;
const forUser = change.data().for;
const notificationContent = {
notification: {
title: title,
body: body,
badge: '1',
click_action: 'FLUTTER_NOTIFICATION_CLICK',
}
};
var usersRef = db.collection('users');
var queryRef = usersRef.where('login', '==', forUser).limit(1).get()
.then(snapshot => {
snapshot.forEach(doc => {
const adminNotifications = doc.data().adminNotifications;
console.log(adminNotifications);
if(swapNotifications === true){
return admin.messaging().sendToDevice(userFcm, notificationContent)
.then(() => {
console.log('notification sent')
return
})
.catch(error =>{
console.log('error in sending notification', error)
})
} else {
console.log('message not send due to swapNotification preferences')
}
return console.log('reading user data success');
})
.catch(err => {
console.log('error in retrieving user data:', err)
})
});