更新2:
仍然在处理同样的问题,但我意识到我的方法可能有缺陷——我不能像在安卓设备上那样,通过Firebase云消息从Parse Server向iOS设备发送推送通知。
相反,据我所知,Parse服务器将根据目标频道订阅的安装,通过Firebase(如果接收设备是Android设备)或通过Apple推送通知服务(如果接收装置是iOS设备)发送推送通知(如果我错了,请纠正我)。
解析服务器向iOS设备发送推送通知需要安装对象中的哪些字段?或者,在iOS设备上创建的安装对象的GCMSenderId和pushType需要保存哪些值?
更新I:
通过Back4App从ParseServer向iOS推送通知仍然不起作用。
我尝试通过云功能发送推送,以绕过Back4App推送面板,并在我的main.js:中实现了一个非常基本的功能
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';
});
我之所以返回一个String,是因为我只是从ParseSwift游乐场复制了一个返回类型为String的模板结构,因为这是一个快速而肮脏的测试。我还不知道如何通过错误处理返回正确的服务器响应。
对应的ParseCloud
结构体:
struct CloudFunction: ParseCloud {
//: Return type of your Cloud Function
typealias ReturnType = String
//: These are required by `ParseCloud`
var functionJobName: String
}
当我调用此函数时,Back4App服务器会响应"pushsample called successfully",推送通知也会出现在Back4App Past Pushes列表中。然而,它只在那里列出,并没有实际交付到我的物理iOS设备。
到目前为止,我还没有使用JavaScript的经验,所以如果有人能告诉我如何更好地解决这个问题,或者从服务器上获得更多的诊断信息,那将是一个很大的帮助。
正如在最初的帖子中所说,我使用Firebase Cloud Messaging,并利用服务器上解析安装对象中保存的Channel属性来针对特定用户。这对于Android版本的应用程序来说是完美的,在使用云代码时也是如此。
对于iOS,我只能通过";发送您的第一条消息";页面,通过其消息令牌定位我的设备。通过Firebase从Back4App通过通道发送推送通知不起作用。
我该怎么解决这个问题?
欢迎任何意见!
我在我的应用程序中使用Parse Server 4.2.0和ParseSwift 2.5.1。
原帖:
我有一个使用Back4App作为后端的Android应用程序,目前正在将其移植到iOS。我一直在努力通过Parse Dashboard(或通常通过我的Parse后端)向iOS应用程序发送推送通知。
在我的Android应用程序中,我使用Firebase Cloud Messaging按照Back4App指南实现了推送通知,这是开箱即用的。我实现了Firebase,注册了推送通知,并在我的分析安装中保存了GCMSenderId和deviceToken,并在Back4App上的Android推送通知服务器设置中注册了Firebase。我可以毫无问题地发送推送通知。
对于iOS版本,我尝试过模仿它。我创建了APN.p8密钥文件,将其上传到Firebase,在我的App Delegate中实现了Firebase,注册了推送通知,在应用程序设置中添加了推送提醒功能,在解析安装中保存了GCMSenderId和deviceToken,还将APN文件上传到Back4App上的iOS推送通知服务器设置中。
有了这个设置,我可以:
- 使用给定的deviceToken从Firebase Cloud Messaging直接向我的Android设备发送推送通知
- 使用给定的deviceToken从Firebase Cloud Messaging直接向我的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)")
}
}
}
}
非常感谢您的帮助!
保存的是false deviceToken-它是Firebase令牌,而不是APN令牌!
以下是我的想法:
我可以从Firebase发送推送通知,但不能从ParseServer发送。我保存的令牌是App Delegate
中messaging
函数中的令牌,这是一个Firebase函数,而不是APN函数。当我在网上读到一个应用程序重新注册APN服务时,我意识到这个令牌从未改变过,因此每次应用程序启动时都会获得一个新的APN令牌。
查看我的日志,我发现我的应用程序从未调用过didRegisterForRemoteNotificationsWithDeviceToken
和didFailToRegisterForRemoteNotificationsWithError
。
是什么解决了这个问题?我在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 Analytics并从我的Parse服务器发送推送通知。