iOS客户端-Firebase云功能。每当在Firestore中创建“项目”时,我都希望将推送通知发送到特定客户端。
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.newMessageNotify = functions.firestore.document('conversation/{uid}/all/{mid}')
.onCreate((change, context) => {
const userID = context.params.uid;
console.log("New message created2 "+ userID);
const getUserPromise = admin.auth().getUser(userID);
const path = '/users/' + userID + '/notificationTokens';
console.log("User path is " + path);
const getDeviceTokensPromise = admin.database()
.ref(path).once('value');
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
return Promise.all([getDeviceTokensPromise, getUserPromise]).then(results => {
tokensSnapshot = results[0];
const user = results[1];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
console.log('Fetched user profile', user);
// Notification details.
const payload = {
notification: {
title: 'You have a new message!',
body: 'Message body'
}
};
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload);
}).then((response) => {
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
});
这是我的云功能,它遵循https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js上的官方文档示例。请注意,对于路径
,我最初也使用了s而不是sadmin.database()
.ref('/users/${userID}/notificationTokens`).once('value');
但不会改变任何事情。我每次都会收到“没有通知令牌可发送给”的消息。
我的iOS客户端设置:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
self.showLogin()
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (success, error) in
if let e = error{
print("Error occurred \(e.localizedDescription)")
}else{
print("Success")
}
}
UIApplication.shared.registerForRemoteNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification(_:)), name: NSNotification.Name.MessagingRegistrationTokenRefreshed, object: nil)
return true
}
@objc func tokenRefreshNotification(_ notification: NSNotification){
let _ = true
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("didReceive reg token")
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("didReceiveRemoteMessage")
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("Did receive")
completionHandler()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Auth.auth().setAPNSToken(deviceToken, type: .sandbox)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("willPresentNotification")
completionHandler(UNNotificationPresentationOptions.alert)
}
现在,有办法调试吗?另外,最让我感到困惑的是,在云功能中,我正在尝试为特定用户获取通知令牌,而在客户端上为设备设置了设备令牌。如何为特定用户设置这些令牌?成功的身份验证后会自动完成吗?据我了解,这是通过自动转换完成的,但是我该如何调试呢?我可以检查管理数据库的内容吗?
我已经使用Firebase仪表板推送了测试通知,并且已经在我的iOS客户端应用中成功接收到通知,这意味着通知可以正常工作。