iosswiftfirebase-cloud-messagingremote-notifications

Attempting to run a function from inside the didReceive response in swift from a remote notification


So I have a setup where I am trying to learn how to do a basic chat app with firebase and swift. I have the notification categories all setup, I can get the notifications, and I can click on the actions I have setup. I started upgrading it to allow a "reply" in the notification actions and that's where I am running into problems.

In my userNotificationCenter method for didReceive response, I need to be able to call my ApiService to send the message off to my node server which communicates directly with firebase via the admin sdk. The problem is, every time I try to call a method from inside that function I get an error:

Type of expression is ambiguous without more context

Here is my didReceive method, simplified for sake of simplicity in this post...

func userNotificaitonCenter(_ center: UNUsernotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  let userInfor = response.notificaiton.request.content.userInfo
  switch response.actionIdentifier {
    case Notifications.Actions.reply:
      let textResponse = response as! UNTextInputNotificationResponse
      let userText = textResponse.userText
      let messageFrom = userInfo["from"]
      let myID = userInfo["to"]
      ApiService.sendNewMessage(myId, to: messageFrom, message: userText) { (_) in } <-This line gives the error
      break
    ...
 }
}

I have tried changing it by adding a private method in my AppDelegate class and then calling that method, but I still get the same error. I don't understand why it thinks that expression is ambiguous, there is no other ApiService class in my project except the one I built. Am I doing this completely wrong? I just want to be able to send the message that the user typed in the notification back to the server so it can be added to the chat. Thank you for any help in advance, this one is making me scratch my head and lose some hair.


Solution

  • There are many typos in this - some are allowed, some would create issues like you are facing.

    /// 1. `userNotificaitonCenter` - typo in Notification - allowed (you may be able to compile with it, SDK won't be able provide you this callback
    /// 2. `center: UNUsernotificationCenter` - small n in notification (invalid type name - not allowed to compile - which you are seeing the compiler complaining about in it's weirdest form)
    /// 3. `response.notificaiton.request.content.userInfo` - typo in `notification` (not allowed to compile)
    /// 4. `let userInfor = ...` vs `userInfo["from"]` - compiler has no idea what `userInfo` is - it only knows about `userInfor` 
    /// 5. `let userInfor = ...` vs `userInfo["to"]` - compiler has no idea what `userInfo` is - it only knows about `userInfor` 
    /// 6. `ApiService.sendNewMessage` - Is it a class/static method or instance method? Do you want to do something like ApiService.shared.sendNewMessage ???
    /// 7. `ApiService.sendNewMessage(myId, to: messageFrom` Does it expect String in both of these parameters? OR Int in first & String in second parameter?
    func userNotificaitonCenter(_ center: UNUsernotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
      let userInfor = response.notificaiton.request.content.userInfo
      switch response.actionIdentifier {
        case Notifications.Actions.reply:
          let textResponse = response as! UNTextInputNotificationResponse
          let userText = textResponse.userText
          let messageFrom = userInfo["from"]
          let myID = userInfo["to"]
          ApiService.sendNewMessage(myId, to: messageFrom, message: userText) { (_) in } <-This line gives the error
          break
        ...
     }
    }
    

    UPDATE

    Here's what it should look like (typos fixed, some dummy ApiService code added to make it compile)

    import Foundation
    import UserNotifications
    
    class ApiService {
        static let shared = ApiService()
        func sendNewMessage(to toID: Int, from fromID: Int, message: String) {}
    }
    
    class Test: NSObject, UNUserNotificationCenterDelegate {
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            let userInfo = response.notification.request.content.userInfo
            switch response.actionIdentifier {
            case "reply":
                let textResponse = response as! UNTextInputNotificationResponse
                let userText = textResponse.userText
                let from = userInfo["from"] as? Int ?? 0
                let to = userInfo["to"] as? Int ?? 0
                ApiService.shared.sendNewMessage(to: to, from: from, message: userText)
                break
            default: break
            }
        }
    }