[ Firebase ] Hướng dẫn gửi notifications với Cloud Functions

May 22, 2017
Categories:
Tags:

Firebase Cloud Functions là gì

Khoảng 3 tháng trước, Firebase có ra tính năng beta là Cloud Functions rất ảo diệu. Tổng quan là bây giờ bạn có thể build backend hoàn toàn với Firebase được rồi.

Bạn có thể trigger event khi database trên Firebase thay đổi hay gọi HTTPs request, kết nối với Machine Learning API của Google và hàng tá thứ khác. Viết code xong deploy trực tiếp lên Firebase luôn, không phải cài đặt server gì hết, Google đã lo cho bạn từ A-Z. Trước đây chưa có Cloud Functions thì bạn phải viết web server để làm mấy việc này.

Mình đã xài Firebase cho những project trước đây, cảm thấy rất hài lòng và tiện. Và bài này cũng được đúc kết trong quá trình mình cài đặt notifications dùng Cloud Functions và FCM

Ý tưởng:

Trong ứng dụng Elite Condos, mình muốn gửi thông báo đến devices khi trạng thái của đơn hàng thay đổi. Cấu trúc database như sau:

Cấu trúc Order

Kết quả nhận được notifications

Kiến thức cần biết

Mình sẽ lược bỏ những thứ linh tinh chỉ tập trung vào các bước chính, những phần mình chưa giải thích sẽ để lại keywords và link documents để các bạn có thể theo dõi nhé.

Các bước mình đã thực hiện:

  1. Gửi notification bằng Firebase Notification Console GUI
  2. Gửi notification đến devices nhất định với token ( vẫn dùng Notification Console GUI  của Firebase )
  3. Gửi notification đến devices nhất định với token bằng cloud functions
  4. Tự động lấy token và gửi notification bằng cloud functions

Mình tự nhận là người học chậm nên cái gì cũng phải chia rõ ra mới hiểu và nhớ được.

Nếu bạn không tin thì có thể xem video hướng dẫn của Google, mình xem vài lần mới hiểu được sơ sơ:

Gửi notification bằng Notification Console GUI

Với IOS, bạn cần có APN để gửi notification. Mà để có APN thì bạn cần đăng ký certification và sau đó upload certificate này lên Firebase

Quá trình đăng ký này khá dễ nhưng bạn nêu chú ý từng bước. Đã có bài hướng dẫn rất kĩ trên medium, bạn có thể xem tại đây.

Sau khi export ra file certificate dạng .p12. Bạn vào Project Settings -> CLOUD MESSAGING và upload những certificate này:

Sau đó vào Notification gửi thử vài cái nào:

Gửi notification đến devices nhất định với token

Để gửi notification đến từng device vì ban đầu mình muốn chỉ những khách hàng và nhà cung cấp có order thay đổi nhận notification mà thôi. Đoạn code dưới đây để lấy token và cập nhật lại token lên database

// // AppDelegate.swift // Elite Condos Supplier // // Created by Khoa on 11/1/16. // Copyright © 2016 Khoa. All rights reserved. //

import UIKit import Firebase import FirebaseInstanceID import FirebaseMessaging @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(\_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: \[UIApplicationLaunchOptionsKey: Any\]?) -> Bool {
    // Override point for customization after application launch.
    FIRApp.configure()
    if #available(iOS 8.0, \*) {
        let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: \[.alert, .badge, .sound\], categories: nil)
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
    } else {
        let types: UIRemoteNotificationType = \[.alert, .badge, .sound\]
        application.registerForRemoteNotifications(matching: types)
        
    }
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotification(notification:)), name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
    return true
}

func applicationWillResignActive(\_ application: UIApplication) {
   
}

func applicationDidEnterBackground(\_ application: UIApplication) {
      }

func applicationWillEnterForeground(\_ application: UIApplication) {
   
}

func applicationDidBecomeActive(\_ application: UIApplication) {
    UIApplication.shared.applicationIconBadgeNumber = 0
    connectToFCM()
       }

func applicationWillTerminate(\_ application: UIApplication) {
  
}

func tokenRefreshNotification(notification: NSNotification) {
    if let token = FIRInstanceID.instanceID().token(){
        Api.User.updateTokenToDatabase(token: token, onSuccess: {
            UserDefaults.standard.setValue(token, forKey: "token")
            print("token in didRegister: \\(token)")
            self.connectToFCM()
        })
        
    }
}
func application(\_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
    
    if let token = FIRInstanceID.instanceID().token(){
        Api.User.updateTokenToDatabase(token: token, onSuccess: {
            UserDefaults.standard.setValue(token, forKey: "token")
            print("token in didRegister: \\(token)")
            self.connectToFCM()
        })
        
    }
}
func connectToFCM() {
    FIRMessaging.messaging().connect { (error) in
        
        if (error != nil) {
            print("Unable to connect to FCM \\(error.debugDescription)")
        } else {
            print("Connected to FCM")
            
        }
    }
}

}

Lúc này, trên database đã lưu lại token của device, tùy theo database của bạn mà bạn lưu token cho phù hợp nhé, thường lưu ở trong user là ổn nhất.

Nhớ lưu token nhé

Khi đó bạn vào lại Notification Console để gửi đến device có token này test thử xem sao?

Trong mục Target, bạn chọn Single device để test tính năng này:

Như vậy là đã xong việc gửi notification đến 1 device nhất định.

Tự động gửi đến devices  bằng Cloud Functions

Mình sẽ bỏ qua bước "Gửi notification đến devices nhất định với token bằng cloud function" luôn nhé. Lúc mình học thì cần bước này để hiểu, còn khi hướng dẫn không thấy bước này cần thiết lắm.

Cloud Functions viết như NodeJS vậy :)). Lời khuyên tốt nhất là nên đọc sơ qua Javascript, npm, NodeJs trước. Sau đó vào Git repos của Cloud Functions và đọc code mẫu để biết cách init project, kết nối với project trên Firebase, cách deploy thế nào.

Link github: https://github.com/firebase/functions-samples

Mình khuyến khích bạn nên xem 2 project mẫu là:

Text Moderation: Tự động thay đổi text bậy bạ, ví dụ user gửi lên database "fuck you. You're son of the bitch" thì function này sẽ đổi thành "**** you.You're son of the ***** ". Ví dụ này, bạn sẽ thấy việc sử dụng được nhữ thư viện của npm như 'bad-words' hiệu quả thế nào.

Send FCM notifications: Gửi notification nhưng trên nền website. Xem xong bạn sẽ hiểu phần nào cách cloud functions hoạt động

Và đây là function gửi notification khi order.status thay đổi. Vì mình phân user thành supplier và customer nên token được lưu ở 2 nơi.

Workflow của đoạn code này như sau:

  1. Xem order nào có giá trị thay đổi
  2. Lấy customerIdsupplierId. Dựa vào đó lấy token của từng device
  3. Tạo payload để gửi notifications.

'use strict';

const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase);

// Moderates messages by lowering all uppercase messages and removing swearwords. exports.sendNotifications = functions.database .ref('/orders/{orderId}').onWrite(event => { const order = event.data.val();

const orderId = event.params.orderId
var statusName = "NOTACCEPTED";

switch (order.status) {
  case 0:
    statusName = "NOTACCEPTED"
    break;
  case 1:
    statusName = "ONGOING"
    break;
  case 2:
    statusName = "CANCEL"
    break;
  case 3:
    statusName = "FINISHED"
    break;
  default:
    statusName = "REJECTED"
    break;
}

console.log('Current status: ', order.status);

console.log('customer id', order.customerId);
console.log('supplier id', order.supplierId);
const customerRef = admin.database().ref(\`/customers/${order.customerId}\`).once('value');
const supplierRef = admin.database().ref(\`/suppliers/${order.supplierId}\`).once('value');
return Promise.all(\[customerRef, supplierRef\]).then(result => {
  const customer = result\[0\].val()
  const supplier = result\[1\].val()
  if (customer.token != null && supplier.token != null) {

    console.log('customer Token = ', customer.token);
    console.log('supplier Token = ', supplier.token);

    const payload = {
      notification: {
        title: \`Elite Condos Notifications\`,
        body: \`Đơn hàng #${orderId} đã thay đổi trạng thái:  ${statusName}\`,
        sound: "default",
        badge: "1"
      }
    };
    var tokens = \[customer.token, supplier.token\];
    console.log(' Tokens array = ', tokens);
    return admin.messaging().sendToDevice(tokens, payload).then(response => {
      console.log('response', response)
    })
  }

})

});

Ngoài ra, nếu bạn mới biết Javascript thì nên tìm hiểu Promise trong Javascript là hiểu được đoạn code trên dễ dàng rồi.

Sau đó bạn deploy lên firebase là xong.

Tổng kết

Bài viết theo phương châm là cho cần câu chứ không cho cá. Mình không hướng dẫn, giải thích chi tiết từng bước. Tại vì nó quá nhiều, thứ hai nữa là bạn cần đọc document thêm để hiểu rõ.

Hy vọng bài viết đã giúp các bạn phần nào về việc gửi notification với Cloud Functions. Mọi ý kiến đóng góp cứ comment nhé.

À, theo mình dự đoán thì tương lai Firebase sẽ rất báo đạo, đương nhiên sẽ có nhiều bài viết mới về Firebase trong tương lai. Hẹn gặp lại.

Author: Khoa Nguyen
https://niviki.com
Thất nghiệp. Đang rủ rê nhiều người thất nghiệp. Nhận làm ứng dụng MVP để nhiều người bỏ việc. Hy vọng với NIVIKI.COM có thể lan toả tinh thần thất nghiệp đến với nhiều người hơn nữa.