Tuesday, October 23, 2018

Ionic 4 + Capacitor + Firebase Messaging + iOS Proof of Concept

Problem:

How to get Firebase FCM device token from iOS device in an Ionic 4.beta and Capacitor 1.0.0-beta.8 project.

Solution:

Capacitor push notifications on an Android device returns an FCM device token. However, iOS devices return an APNS device token. Firebase is unable to send a message with an APNS token. However, the APNS token could be used to send a message via Apple's Push Notification Service.

To get an FCM on an iOS device, follow the instructions here for setting up a Firebase Cloud Message Client App on iOS: https://firebase.google.com/docs/cloud-messaging/ios/client

Proof of Concept (in short):

a. Add Firebase pods to /ios/App/Podfile


target 'App' do
  # Add your Pods here
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'

b. Run in the console in /ios/App: pod install

c. In /ios/App/App/AppDelegate.swift insert the following:

// part 1 of 3

import UserNotifications
import Firebase

// part 2 of 3

// Override point for customization after application launch.
    
    // Use Firebase library to configure APIs
    FirebaseApp.configure()
    
    Messaging.messaging().delegate = self
    
    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 })
    } else {
        let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(settings)
    }
    
    application.registerForRemoteNotifications()

// part 3 of 3
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
        
        let dataDict:[String: String] = ["token": fcmToken]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }

Friday, October 12, 2018

Angular 6 Component Require JSON ExpressionChangedAfterItHasBeenCheckedError

Problem:

In an Angular 6 project, a simple component that gets json data from a local file generates error: ExpressionChangedAfterItHasBeenCheckedError

Solution:

Do not use the following method to import local json data into the component:
const data = require('./data.json');

Use other standard approaches e.g.

this.http.get(this.dataUrl).subscribe((data: any) => {
    // Do something with json data!
});