当使用sendToDevice从firebase功能发送到iOS设备时,我如何使推送通知工作



我正在尝试让推送通知在iOS上运行。当使用";发送";,但在使用";sendToDevice";。这真的很奇怪。我遵守了这里的所有说明(https://firebase.google.com/docs/cloud-messaging/ios/client),但它仍然不起作用。我已经在我的开发者帐户和Firebase控制台中设置了APN文件,我可以直接从Firebase面板发送推送。我已经附上了我的firebase函数代码以及我的AppDelegate。我做错了什么?谢谢你的帮助。


import UIKit
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

let notificationCenter = UNUserNotificationCenter.current()
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> 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 you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)

// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: (error.localizedDescription)")
}

// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: (deviceToken)")
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: (String(describing: fcmToken))")
//todo see if i need this code here
let dataDict:[String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)

// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
UserDefaults.standard.setValue(fcmToken, forKey: "LATEST_FCM_TOKEN")
if(Auth.auth().currentUser != nil){
self.updateUsersFcmToken(token: fcmToken!)
}else{

}
}

private func updateUsersFcmToken(token: String) {

Firestore.firestore().collection("Users").document(Auth.auth().currentUser!.uid).collection("fcmTokens").document(token).setData([
"token": token, "os": "iOS"
], merge: true) { err in
if let err = err {
print("Error saving latest token: (err)")
} else {
UserDefaults.standard.setValue(token, forKey: token + "_" + Auth.auth().currentUser!.uid)
}
}
}


}

extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
print("did receive")
Messaging.messaging().appDidReceiveMessage(userInfo)
// Change this to your preferred presentation option
completionHandler([[.alert, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("did receive")
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler()
}
}

exports.createdLostPetAlerts = functions.firestore
.document("Lost/{lostPetId}")
.onCreate((snap, context) => {

const registrationToken = "FCM_TOKEN_HERE";

//This works.
// const message = {
//   data: {
//     score: '850',
//     time: '2:45'
//   },
//   token: registrationToken
// };

// // Send a message to the device corresponding to the provided
// // registration token.
// admin.messaging().send(message)
//   .then((response) => {
//     // Response is a message ID string.
//     console.log('Successfully sent message:', response);
//   })
//   .catch((error) => {
//     console.log('Error sending message:', error);
//   });

//This does not work.
const payloadIos = {
"data" : {
"lostPetId" : "12345",
"lostPetName": "Fido",
"messageType": "1"
},
"token": registrationToken
}
admin.messaging().sendToDevice(registrationToken, payloadIos)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
}

事实证明,iOS要求您传递标题和正文,否则它不会显示通知。像这样的东西行得通。

const payload = {
"notification":{
"title": "Needed title",
"body": "Needed body"
},
"data" : {
"lostPetId" : context.params.lostPetId,
"lostPetName": lostPet.name,
"messageType": "1"
}
}

相关内容

  • 没有找到相关文章

最新更新