应用程序在后台时的 Firebase 侦听器

人气:553 发布:2022-10-16 标签: ios firebase swift firebase-cloud-messaging unnotificationrequest

问题描述

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

I have a Firebase childAdded event listener for the notifications table in my app that I would like to trigger push notifications when the app is in the background.

这里是监听器:

@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 方法在后台观察它:

This works great when the app is in the foreground. I then add a background observer in my app delegates applicationWillResignActive method to observe it in the background:

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

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

But the event observer doesn't fire when the app is in the background. Ive looked into Firebase Cloud Messenger to solve this problem and come across posts like this:

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

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

however I'm not trying to send a push notification from one user to another, I'm trying to activate a UNNotificationRequest from within the database listener.

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

I also found this post: FCM background notifications not working in iOS but again, this differs from my use case because its being used within the FIRMessaging framework.

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

推荐答案

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

Devices have their own way of managing background network calls so handling background push notifications like this will not work on real devices. The observers are removed from memory shortly after the app goes into the background. I was able to solve this by creating a Node.js server which observes the notifications table and handles push notifications using the Firebase-Messenger framework. It was actually pretty easy. I used this blog post as my guide: Sending notifications between Android devices with Firebase Database and Cloud Messaging

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

This method will work however in the simulator (but not on real devices) so long as you pass the object containing the observer (the app delegate in this case) to background thread call like this:

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

915