我的应用中的通知表有一个Firebase childAdded
事件侦听器,当应用在后台时,我想触发推送通知。
以下是听众:
@objc func observeNotificationsChildAddedBackground() {
self.notificationsBackgroundHandler = FIREBASE_REF!.child("notifications/\(Defaults.userUID!)")
self.notificationsBackgroundHandler!.queryOrdered(byChild: "date").queryLimited(toLast: 99).observe(.childAdded, with: { snapshot in
let newNotificationJSON = snapshot.value as? [String : Any]
if let newNotificationJSON = newNotificationJSON {
let status = newNotificationJSON["status"]
if let status = status as? Int {
if status == 1 {
self.sendPushNotification()
}
}
}
})
}
func sendPushNotification() {
let content = UNMutableNotificationContent()
content.title = "Here is a new notification"
content.subtitle = "new notification push"
content.body = "Someone did something which triggered a notification"
content.sound = UNNotificationSound.default()
let request = UNNotificationRequest(identifier: "\(self.notificationBackgroundProcessName)", content: content, trigger: nil)
NotificationCenter.default.post(name: notificationBackgroundProcessName, object: nil)
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().add(request){ error in
if error != nil {
print("error sending a push notification :\(error?.localizedDescription)")
}
}
}
当应用程序位于前台时,这非常有用。然后我在我的app委托applicationWillResignActive
方法中添加了一个背景观察器,以便在后台观察它:
func applicationWillResignActive(_ application: UIApplication) {
NotificationCenter.default.addObserver(self, selector: #selector(MainNavViewController.observeNotificationsChildAdded), name: notificationBackgroundProcessName, object: nil)
}
但是当应用程序在后台时,事件观察者不会触发。我调查了Firebase Cloud Messenger来解决这个问题并遇到这样的帖子:
但是我并没有尝试从一个用户向另一个用户发送推送通知,我正在尝试从数据库侦听器中激活UNNotificationRequest
。
我也发现这篇文章:
FCM background notifications not working in iOS
但同样,这与我的用例不同,因为它在FIRMessaging
框架内使用。
那么,当应用程序在后台时,是否可以运行此数据库侦听器?如果没有,我是否可以让Firebase Cloud Messenger观察表中的更改并发送通知?
答案 0 :(得分:3)
我遇到了同样的问题,几个月前发现了你的帖子。我已经设法最终了解在后台观察通知所需的内容。
我详细介绍了我在这篇文章中使用的解决方案https://stackoverflow.com/a/42240984/7048719
技术如下
这样观察者就会留在记忆中
更新:Apple已针对后台模式实施了更新,这些更新已停止此方法的运行。
答案 1 :(得分:1)
设备有自己管理后台网络呼叫的方式,因此处理这样的后台推送通知将无法在真实设备上运行。应用程序进入后台后不久,观察者将从内存中删除。我能够通过创建一个观察notifications
表并使用Firebase-Messenger框架处理推送通知的Node.js服务器来解决这个问题。这实际上非常简单。我用这篇博文作为我的向导:
Sending notifications between Android devices with Firebase Database and Cloud Messaging
然而,只要将包含观察者(在本例中为app委托)的对象传递给后台线程调用,此方法将在模拟器(但不在实际设备)中起作用:
func applicationWillResignActive(_ application: UIApplication) {
NotificationCenter.default.addObserver(self,
selector: #selector(self.observeNotificationsChildAddedBackground),
name: notificationBackgroundProcessName,
object: self)
}
答案 2 :(得分:1)
简单的解决方案是使用后台提取。您还可以使用后台提取来定期获取新条目的表,并在添加新行时显示通知。
这并不能确保立即收到通知。但与使用APN相比,实现要简单得多。
答案 3 :(得分:0)
您可以将后台任务添加到Firebase观察器
@objc函数funcobserveNotificationsChildAddedBackground(){
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
backgroundTask = UIApplication.shared.beginBackgroundTask {
[unowned self] in
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
assert(backgroundTask != UIBackgroundTaskInvalid)
self.notificationsBackgroundHandler = FIREBASE_REF!.child("notifications/\(Defaults.userUID!)")
self.notificationsBackgroundHandler!.queryOrdered(byChild: "date").queryLimited(toLast: 99).observe(.childAdded, with: { snapshot in
let newNotificationJSON = snapshot.value as? [String : Any]
if let newNotificationJSON = newNotificationJSON {
let status = newNotificationJSON["status"]
if let status = status as? Int {
if status == 1 {
self.sendPushNotification()
}
}
}
})
}