From c3614117289851f7d9a95f83d60805647c9cceb0 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 24 Dec 2021 00:15:14 -0800 Subject: [PATCH] asking for notification permissions on authentication for more reliability for it to work off the bat and permissions for notifications --- .../Services/PushNotificationService.swift | 46 ++++++++++++++++++- .../Views/InnerCircle/InnerCircleView.swift | 4 +- .../InnerCircle/InnerCircleViewModel.swift | 13 ++++-- nirvana-ios/nirvana_iosApp.swift | 25 +--------- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/nirvana-ios/Services/PushNotificationService.swift b/nirvana-ios/Services/PushNotificationService.swift index d52e8a0..647f5a5 100644 --- a/nirvana-ios/Services/PushNotificationService.swift +++ b/nirvana-ios/Services/PushNotificationService.swift @@ -6,8 +6,14 @@ // import Foundation +import Firebase +import FirebaseFirestore +import FirebaseMessaging +import UserNotifications +import UIKit -class PushNotificationService { +class PushNotificationService: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate { + let firestoreService = FirestoreService() func sendPushNotification(to token: String, title: String, body: String) { let urlString = "https://fcm.googleapis.com/fcm/send" @@ -34,5 +40,43 @@ class PushNotificationService { } task.resume() } + + func registerForPushNotifications() { + 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 }) + // For iOS 10 data message (sent via FCM) + Messaging.messaging().delegate = self + } else { + let settings: UIUserNotificationSettings = + UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) + UIApplication.shared.registerUserNotificationSettings(settings) + } + UIApplication.shared.registerForRemoteNotifications() + } + + func updateFirestorePushTokenIfNeeded() { + if let deviceToken = Messaging.messaging().fcmToken { + if let user = Auth.auth().currentUser { + // User is signed in. + print("have access to user Id when I received registration token: \(user.uid)") + + // kind of have to store in database or update every time, because don't know if the user logged in and out or if there is a new token or not + // https://firebase.google.com/docs/cloud-messaging/ios/client#access_the_registration_token + + firestoreService.updateUserDeviceToken(userId: user.uid, deviceToken: deviceToken) { res in + print(res) + } + } else { + // No user is signed in. + // ... + print("can't save user device token to a user") + } + } + } } diff --git a/nirvana-ios/Views/InnerCircle/InnerCircleView.swift b/nirvana-ios/Views/InnerCircle/InnerCircleView.swift index cab7b14..5b9bb30 100644 --- a/nirvana-ios/Views/InnerCircle/InnerCircleView.swift +++ b/nirvana-ios/Views/InnerCircle/InnerCircleView.swift @@ -143,7 +143,9 @@ struct InnerCircleView: View { // activate 3 data listeners once for authsessionstore/usermanager if not already called, but authsessionstore will handle that self.authSessionStore.activateMainDataListeners() - // save device token + // set up push notifications and such + save up to date device token + // TODO: this is firing too often? + self.innerCircleVM.setUpPushNotifications() } // .onDisappear { // print("deiniting data listeners, but current data should still be cached!") diff --git a/nirvana-ios/Views/InnerCircle/InnerCircleViewModel.swift b/nirvana-ios/Views/InnerCircle/InnerCircleViewModel.swift index 501c27c..87422c0 100644 --- a/nirvana-ios/Views/InnerCircle/InnerCircleViewModel.swift +++ b/nirvana-ios/Views/InnerCircle/InnerCircleViewModel.swift @@ -18,9 +18,9 @@ class InnerCircleViewModel: ObservableObject { private var audioLocalUrl: URL? - let cloudStorageService = CloudStorageService() - let firestoreService = FirestoreService() - let pushNotificationService = PushNotificationService() + private let cloudStorageService = CloudStorageService() + private let firestoreService = FirestoreService() + private let pushNotificationService = PushNotificationService() init() { do { @@ -32,7 +32,6 @@ class InnerCircleViewModel: ObservableObject { print("Can not setup the Recording") } } - } // audio stuff @@ -104,5 +103,9 @@ extension InnerCircleViewModel { // handling saving device token for notifications extension InnerCircleViewModel { - + func setUpPushNotifications() { + self.pushNotificationService.registerForPushNotifications() + + self.pushNotificationService.updateFirestorePushTokenIfNeeded() + } } diff --git a/nirvana-ios/nirvana_iosApp.swift b/nirvana-ios/nirvana_iosApp.swift index 2cd3c09..55e2b76 100644 --- a/nirvana-ios/nirvana_iosApp.swift +++ b/nirvana-ios/nirvana_iosApp.swift @@ -123,7 +123,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { - print("failed ot register for remote notifications with error: \(error)") + print("failed to register for remote notifications with error: \(error)") } } @@ -140,29 +140,6 @@ extension AppDelegate: MessagingDelegate { ) // Note: This callback is fired at each app startup and whenever a new token is generated. - let firestoreService = FirestoreService() - let user = Auth.auth().currentUser - - // TODO: store it on loading of circle view and not on launch as this may just never get called - // use the notification center above - // https://stackoverflow.com/questions/58818046/how-to-set-addobserver-in-swiftui - if user != nil && fcmToken != nil { - // User is signed in. - // ... - print("have access to user Id when I received registration token: \(user!.uid)") - - // kind of have to store in database or update every time, because don't know if the user logged in and out or if there is a new token or not - // https://firebase.google.com/docs/cloud-messaging/ios/client#access_the_registration_token - - firestoreService.updateUserDeviceToken(userId: user!.uid, deviceToken: fcmToken!) { res in - print(res) - } - } else { - // No user is signed in. - // ... - print("can't save user device token to a user") - } - } }