iOS-клиент - облачная функция Firebase.Всякий раз, когда в пожарном хранилище создается «предмет», я хочу отправить push-уведомление конкретному клиенту.
'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 вместо 'изначально для пути
admin.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)
}
Теперь, есть ли способ отладить это?Кроме того, меня больше всего смущает то, что в облачной функции я пытаюсь получить токены уведомлений для конкретного пользователя, в то время как на клиенте для устройства устанавливается токен устройства.Как эти токены установлены для конкретного пользователя?Это делается автоматически после успешной аутентификации?Насколько я понимаю, это происходит автоматически через swizzling, но как мне отладить его тогда?Могу ли я проверить содержимое базы данных администратора?
Я отправил тестовое уведомление с помощью панели управления firebase и успешно получаю уведомление в своем клиентском приложении для iOS, что означает, что уведомления работают.