Firebase chat Push Notifications


Answers

There are two features in the new Firebase to send notifications to users:

  • Firebase Cloud Messaging - the next generation of Google Cloud Messaging
  • Firebase Notifications - built on top of Cloud Messaging, which allow you to easily send notifications to users through the Firebase Console

To send messages with Cloud Messaging, you need to specify an Authorization Key in a request. Since knowing this key allows sending of messages on your behalf, you'll want to limit access to it to trusted processes. This indeed can be a server, but any trusted process is fine.

Question

I am developing a chat app using Firebase as backend. It is required that on every new message receiver gets a push notification saying that he got a new message. This is first time I am doing something like this so I have a question:

Since we do not use our own server for this, do we need a 3rd party provider (like Batch for example) for handling push notifications? If I am not mistaken I think Firebase does not support sending push notifications like this but only ones you send from console.

Any help would be great.




iOS Firebase Push Notifications : How To Give Firebase User's Device Token And Send Notification

Updated: As of Firebase 4.0.4, you can follow https://github.com/onmyway133/blog/issues/64

HOW APNS DEVICE TOKEN IS HANDLED

I've been reading Send a Notification to a User Segment on iOS but there is no mention of APNS device token, which is crucial to push notifications.

So Firebase must be doing some swizzling under the hood. In fact it is. Reading backend documentation Downstream Messages gives us the idea

Swizzling disabled: mapping your APNs token and registration token

If you have disabled method swizzling, you'll need to explicitly map your APNs token to the FCM registration token. Override the

methods didRegisterForRemoteNotificationsWithDeviceToken to retrieve the APNs token, and then call setAPNSToken.

func application(application: UIApplication,
                   didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenTypeSandbox)
}

I particularly try to avoid swizzling as much as possible. Reading Migrate a GCM Client App for iOS to Firebase Cloud Messaging gives us how to do disable it

Enabling/disabling method swizzling

Method swizzling available with FCM simplifies your client code. However, for developers who prefer not to use it, FCM allows you to disable method swizzling by adding the FIRMessagingAutoRegisterEnabledflag in the app’s Info.plist file and setting its value to NO (boolean value).

FCM swizzling affects how you handle the default registration token, and how you handle downstream message callbacks. Where

applicable, this guide provides migration examples both with and without method swizzling enabled.

SHOW ME THE CODE

Have this in your Podfile

pod 'Firebase'
pod 'FirebaseMessaging'

Here is the completed code

import Firebase
import FirebaseMessaging

override func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  FIRApp.configure()

  NSNotificationCenter.defaultCenter().addObserver(self,
                                                   selector: #selector(tokenRefreshNotification(_:)),
                                                   name: kFIRInstanceIDTokenRefreshNotification,
                                                   object: nil)
}

// NOTE: Need to use this when swizzling is disabled
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
}

func tokenRefreshNotification(notification: NSNotification) {
  // NOTE: It can be nil here
  let refreshedToken = FIRInstanceID.instanceID().token()
  print("InstanceID token: \(refreshedToken)")

  connectToFcm()
}

func connectToFcm() {
  FIRMessaging.messaging().connectWithCompletion { (error) in
    if (error != nil) {
      print("Unable to connect with FCM. \(error)")
    } else {
      print("Connected to FCM.")
    }
  }
}

public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
  print(userInfo)
}



Docs are pretty poor for the FCM for iOS now.

Follow the sample app they have on github

Important part added here :

import Firebase
import FirebaseInstanceID
import FirebaseMessaging

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Register for remote notifications
    if #available(iOS 8.0, *) {
      let settings: UIUserNotificationSettings =
      UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
      application.registerUserNotificationSettings(settings)
      application.registerForRemoteNotifications()
    } else {
      // Fallback
      let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
      application.registerForRemoteNotificationTypes(types)
    }

    FIRApp.configure()

    // Add observer for InstanceID token refresh callback.
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
        name: kFIRInstanceIDTokenRefreshNotification, object: nil)

    return true
  }

 func tokenRefreshNotificaiton(notification: NSNotification) {
    let refreshedToken = FIRInstanceID.instanceID().token()!
    print("InstanceID token: \(refreshedToken)")

    // Connect to FCM since connection may have failed when attempted before having a token.
    connectToFcm()
  }
  // [END refresh_token]

  // [START connect_to_fcm]
  func connectToFcm() {
    FIRMessaging.messaging().connectWithCompletion { (error) in
      if (error != nil) {
        print("Unable to connect with FCM. \(error)")
      } else {
        print("Connected to FCM.")
      }
    }
  }

Now your token has been sent to the FCM server




There are two features in the new Firebase to send notifications to users:

  • Firebase Cloud Messaging - the next generation of Google Cloud Messaging
  • Firebase Notifications - built on top of Cloud Messaging, which allow you to easily send notifications to users through the Firebase Console

To send messages with Cloud Messaging, you need to specify an Authorization Key in a request. Since knowing this key allows sending of messages on your behalf, you'll want to limit access to it to trusted processes. This indeed can be a server, but any trusted process is fine.




Firebase: How to observe a node and send push notifications to clients?

With Firebase client sdk you can register listeners for node events on the client side. Then Firebase will do the magic to notify the client on node events.







Tags