5

我的应用程序中有一个通知表的 FirebasechildAdded事件侦听器,我想在应用程序处于后台时触发推送通知。

这是听众:

@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)")
        }
    }
}

当应用程序在前台时,这非常有用。然后我在我的应用程序委托applicationWillResignActive方法中添加一个后台观察者以在后台观察它:

func applicationWillResignActive(_ application: UIApplication) {
     NotificationCenter.default.addObserver(self, selector: #selector(MainNavViewController.observeNotificationsChildAdded), name: notificationBackgroundProcessName, object: nil)
}

但是当应用程序在后台时,事件观察者不会触发。我研究了 Firebase Cloud Messenger 来解决这个问题,并遇到了这样的帖子:

是否可以使用 Firebase 云消息传递 (FCM) 直接从设备将 PushNotifications 发送到特殊的 UDID?

但是,我并没有尝试从一个用户向另一个用户发送推送通知,而是尝试UNNotificationRequest从数据库侦听器中激活一个。

我还发现了这篇文章: FCM 后台通知在 iOS 中不起作用, 但同样,这与我的用例不同,因为它在FIRMessaging框架内使用。

那么,是否可以在应用程序在后台时运行此数据库侦听器?如果没有,我是否可以让 Firebase Cloud Messenger 观察表格中的变化并发送通知?

4

4 回答 4

3

我有同样的问题,几个月前遇到了你的帖子。我终于明白了在后台观察通知需要什么。

我已经详细介绍了我在这篇文章中使用的解决方案https://stackoverflow.com/a/42240984/7048719

该技术如下

  1. 使用自定义数据服务类
  2. 初始化数据服务类的 sharedInstance
  3. 从初始视图控制器调用数据服务类 sharedInstance 中的适当函数。

这样观察者就留在记忆中

更新: Apple 已针对后台模式实施了更新,这些更新已停止此方法的工作。

于 2017-05-26T02:07:39.047 回答
2

设备有自己管理后台网络呼叫的方式,因此处理这样的后台推送通知在真实设备上不起作用。应用程序进入后台后不久,观察者就会从内存中删除。我可以通过创建一个 Node.js 服务器来解决这个问题,该服务器notifications使用 Firebase-Messenger 框架观察表格并处理推送通知。这实际上很容易。我使用这篇博文作为我的指南: 使用 Firebase 数据库和云消息传递在 Android 设备之间发送通知

但是,只要您将包含观察者的对象(在本例中为应用程序委托)传递给后台线程调用,此方法就可以在模拟器中工作(但不能在真实设备上),如下所示:

func applicationWillResignActive(_ application: UIApplication) {
     NotificationCenter.default.addObserver(self,
                                            selector: #selector(self.observeNotificationsChildAddedBackground),
                                            name: notificationBackgroundProcessName,
                                            object: self)
}
于 2017-01-31T22:23:17.083 回答
1

简单的解决方案是使用后台获取。您还可以使用后台获取定期获取表中的新条目,并在添加新行时显示通知。

这并不能保证立即收到通知。但是与使用 APN 相比,实现要简单得多。

于 2017-04-24T22:12:18.990 回答
0

您可以将后台任务添加到 firebase 观察者

@objc func observeNotificationsChildAddedBackground() {

      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()
                   }
            }
         }
     })
}
于 2019-04-15T15:30:04.020 回答