繁体   English   中英

通过 Parse Server 的 Back4App 推送通知不适用于 iOS

[英]Back4App push notifications via Parse Server not working for iOS

更新 2:

仍在处理同样的问题,但我意识到我的方法可能存在缺陷 - 我无法通过 Firebase Cloud Messaging 从 Parse Server 向 iOS 设备发送推送通知,就像我为 ZE84E30B9390CDB64DAB86DB2C 设备所做的那样。

相反,据我了解,Parse 服务器将通过 Firebase 发送推送通知(如果接收设备是 Android 设备)或通过 Apple 推送通知服务(如果接收设备是 Z1BDF605991920DBZ11 设备CBDF8508 安装)订阅了目标频道(如果我错了,请纠正我)。

安装 object 中的哪些字段是解析服务器向 iOS 设备发送推送通知所必需的? 或者需要为在 iOS 设备上创建的安装对象的 GCMSenderId 和 pushType 保存哪些值?

更新一:

通过 Back4App 从 ParseServer 向 iOS 推送通知仍然不起作用。

我尝试通过 Cloud function 发送推送以绕过 Back4App 推送仪表板,并在我的 main.js 中实现了一个非常基本的 function:

Parse.Cloud.define('pushsample', async () => {
       
       Parse.Push.send({
         channels: ["TestChannelForMyiOSDevice"],
            data: {
                title: "Hello from Cloud Code",
                alert: "It finally worked!",
            }
        }, { useMasterKey: true });
      
      return 'pushsample called successfully';
});

我返回一个字符串,因为我只是从 ParseSwift 操场复制了一个具有返回类型字符串的模板结构,因为这是一个快速而肮脏的测试。 我还没有弄清楚如何通过错误处理返回正确的服务器响应。

对应的ParseCloud结构:

struct CloudFunction: ParseCloud {

    //: Return type of your Cloud Function
    typealias ReturnType = String

    //: These are required by `ParseCloud`
    var functionJobName: String

}

当我调用此 function 时,Back4App 服务器确实以“成功调用推送样本”响应,并且推送通知也出现在 Back4App 过去推送列表中。 但是,它仅在此处列出,并未实际交付给我的物理 iOS 设备。

到目前为止,我还没有使用 JavaScript 的经验,所以如果有人能告诉我如何更好地解决这个问题或从服务器获取更多诊断信息,那将是一个很大的帮助。

如原始帖子中所述,我使用 Firebase 云消息传递并利用保存在我服务器上 Parse Installation 对象中的 Channel 属性来定位特定用户。 这适用于应用程序的 Android 版本,在使用 Cloud Code 时也是如此。

对于 iOS,我只能通过“发送您的第一条消息”页面直接从 Firebase 发送推送通知,并通过其消息令牌定位我的设备。 通过 Firebase 从 Back4App 的频道发送推送通知不起作用。

我怎样才能解决这个问题?

欢迎任何意见!

我在我的应用程序中使用 Parse Server 4.2.0 和 ParseSwift 2.5.1。

 


原帖:

我有一个 Android 应用程序,它使用 Back4App 作为后端,目前正在将其移植到 iOS。 我一直在努力通过 Parse Dashboard(或通过我的 Parse 后端)向 iOS 应用程序发送推送通知。

在我的 Android 应用程序中,我使用 Firebase 云消息传递按照 Back4App 指南实现了推送通知,它开箱即用。 我实现了 Firebase,注册了推送通知,并在我的解析安装中保存了 GCMSenderId 和 deviceToken,并在 Android 中注册了 Firebase,并且可以毫无问题地在推送通知服务器设置上推送通知。

对于 iOS 版本,我尝试对此进行仿真。 我创建了 APN.p8 密钥文件,将其上传到 Firebase,在我的 App Delegate 中实现 Firebase,注册推送通知,在 App 设置中添加推送通知功能,在我的 Parse 安装中保存 GCMSenderId 和 deviceToken,还上传了APN 文件到 Back4App 上的 iOS 推送通知服务器设置。

使用此设置,我可以:

  • 使用给定的 deviceToken 将来自 Firebase 云消息传递的推送通知直接发送到我的 Android 设备
  • 使用给定的 deviceToken 将来自 Firebase 云消息传递的推送通知直接发送到我的 iOS 设备
  • 从 ParseDashboard 向我的 Android 设备发送推送通知(例如,基于安装中的订阅频道)
  • 无法从 ParseDashboard 向我的 iOS 设备发送推送通知

在发送推送通知时(根据 ParseDashboard),它们没有发送到我的 iOS 设备。 我想通过 Parse 发送推送,以便我可以使用与 Android 应用程序相同的基于渠道的分发系统。

我认为这是我的 Back4App 后端某处的问题,因此我尝试将 Back4App iOS 推送设置的 APN Auth 密钥部分中的“生产”值设置为 true 和 false,但两种方式都不起作用。

我怎样才能解决这个问题?

我最近开始了 iOS 编程,到目前为止,我一直在为应用程序使用 SwiftUI,所以我对 App Delegate 生命周期事件非常不熟悉,但能够让它工作到这一点。 这是我目前使用的在上面列出的场景中工作的内容:

class AppDelegate: NSObject, UIApplicationDelegate {
    let gcmMessageIDKey = "gcm.message_id"

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()

        Messaging.messaging().delegate = self

        if #available(iOS 10.0, *) {
          // For iOS 10 display notification (sent via APNS)
          UNUserNotificationCenter.current().delegate = self

          let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
          UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: {_, _ in })
        } else {
          let settings: UIUserNotificationSettings =
          UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
          application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

      if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
      }

      print(userInfo)

      completionHandler(UIBackgroundFetchResult.newData)
    }
    
}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

  // Receive displayed notifications for iOS 10 devices.
  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              willPresent notification: UNNotification,
    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo

    if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
    }

    print(userInfo)

    completionHandler([[.banner, .badge, .sound]])
  }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
        print("didRegisterForRemoteNotificationsWithDeviceToken: token: \(deviceToken)")
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        
        print("application:didFailToRegisterForRemoteNotificationsWithError: %@", error)
        
    }

  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              didReceive response: UNNotificationResponse,
                              withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo

    if let messageID = userInfo[gcmMessageIDKey] {
      print("Message ID from userNotificationCenter didReceive: \(messageID)")
    }

    print(userInfo)

    completionHandler()
  }
}

extension AppDelegate: MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {

        guard let deviceTokenFirebase = fcmToken else { return }
        
        var currentInstallation = Installation.current
        currentInstallation?.pushType = "gcm"
        currentInstallation?.GCMSenderId = "mySenderId"
        currentInstallation?.deviceToken = deviceTokenFirebase
        currentInstallation?.save { results in
            
            switch results {
            case .success(let savedInstallation):
                print("Successfully save installation: \(savedInstallation)")
            case .failure(let error):
                print("Failed to update installation: \(error)")
            }
        }  
        
    }
}

任何帮助深表感谢!

保存的是错误的 deviceToken - 它是 Firebase 令牌,而不是 APN 令牌!

这是我的想法:

我能够从 Firebase 发送推送通知,但不能从 ParseServer 发送推送通知。 The token that I had saved was the token from within the messaging function in my App Delegate - which is a Firebase function, not an APN function. 我意识到这个令牌从未改变,而我在网上看到一个应用程序重新注册了 APN 服务,因此每次应用程序启动时都会获得一个新的 APN 令牌。

检查我的日志,我发现我的应用程序从未调用过didRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithError

什么解决了问题? 我在我的didFinishLaunchingWithOptions中注释掉了 Firebase 部分:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

        // FirebaseApp.configure()

        // Messaging.messaging().delegate = self

        if #available(iOS 10.0, *) {
          // For iOS 10 display notification (sent via APNS)
          UNUserNotificationCenter.current().delegate = self

          let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
          UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: { (granted, error) in
                if let error = error {
                    print("requestAuthorization error: \(error)")
                } else if granted {
                    DispatchQueue.main.async {
                        print("granted: now registeringForRemoteNotifications()")
                        UIApplication.shared.registerForRemoteNotifications()
                    }
                }
            })
        } else {
          let settings: UIUserNotificationSettings =
          UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
          application.registerUserNotificationSettings(settings)
        }

        return true
    }

我认为 Firebase 以某种方式阻止了 APN 函数被调用。 由于我不再需要 Firebase 云消息传递,我将只使用 Firebase 分析并从我的 Parse 服务器发送我的推送通知。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM