Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Firebase Cloud Messaging 入門編

miup
February 20, 2018

Firebase Cloud Messaging 入門編

Firebase.Yebisu #2 発表資料

miup

February 20, 2018
Tweet

More Decks by miup

Other Decks in Programming

Transcript

  1. Firebase
    Cloud Messaging
    ೖ໳ฤ
    Firebase.Yebisu #2

    View Slide

  2. Who am I
    ࡾӜ࿨໵(miup)
    • Cookpad, Komerco ࣄۀ෦
    • iOS Engineer
    • ΍͍ͬͯΔ͜ͱ
    http://techlife.cookpad.com/entry/2018/02/09/102554

    View Slide

  3. ࠓ೔࿩͢͜ͱ
    • Firebase Cloud Messaging (FCM) ʹ͍ͭͯ
    • ࣮૷
    • σϞ

    View Slide

  4. Firebase Cloud Messaging
    • APNs, GCM Λ͍͍ײ͡ʹ΍ͬͯ͘ΕΔ
    Firebase ͷ௨஌ج൫

    View Slide

  5. ͍͍ײ͡ʁ

    View Slide

  6. ۩ମతʹʢػೳ໘ʣ
    • OS ͝ͱɺΞϓϦ͝ͱͷૹ৴ʢίϯιʔϧʣ
    • Topic ͷ֓೦ ( ΧςΰϦΈ͍ͨͳ΋ͷ )
    • Topic ୯ҐͰͷ௨஌ͷडऔ͕Մೳ
    • ϢʔβʔͷߦಈΛτϦΨʔʹϑΥϩϫʔʹ
    ௨஌

    View Slide

  7. ۩ମతʹʢ෼ੳʣ
    • ։෧཰Λऔͬͯ͘ΕΔ
    • ΠϕϯτΛࢦఆͯ͠ίϯόʔδϣϯ΋ग़ͯ͘͠
    ΕΔ
    • ௨஌ͷ AB ςετ

    View Slide

  8. Ͱ΋࣮૷͸೉͍͠ΜͰ͠ΐ͏ʁ

    View Slide

  9. ࣮૷
    • ௨஌ڐ୚Λग़͢
    • Token ؅ཧ
    • ઀ଓɺडऔ

    View Slide

  10. ࣮૷ (ೝূ)
    // ೝূ (iOS 10 Ҏ্Λ૝ఆ)
    Messaging.messaging().delegate = self
    UNUserNotificationCenter.current().delegate = self
    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(
    options: authOptions,
    completionHandler: {_, _ in })
    UIApplication.shared.registerForRemoteNotifications()

    View Slide

  11. ࣮૷ (Token औಘ)
    // implement MessagingDelegate
    extension AppDelegate: MessagingDelegate {
    public func messaging(
    _ messaging: Messaging,
    didReceiveRegistrationToken fcmToken: String) {
    print(fcmToken)
    }
    }

    View Slide

  12. ࣮૷ (subscribe)
    guard Messaging.messaging().fcmToken != nil else { return }
    // subscribe
    Messaging.messaging().shouldEstablishDirectChannel = true
    // unsubscribe
    Messaging.messaging().shouldEstablishDirectChannel = false

    View Slide

  13. ࣮૷ (subscribe topic)
    // subscribe topic
    Messaging.messaging().subscribe(toTopic: “TopicName”)
    // unsubscribe topic
    Messaging.messaging().unsubscribe(toTopic: “TopicName")

    View Slide

  14. ࣮૷ (Message Handling)
    // ϑΥΞάϥ΢ϯυͰͷ௨஌ͷड৴
    extension AppDelegate: UNUserNotificationCenterDelegate {
    public func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler:
    @escaping (UNNotificationPresentationOptions) -> Void) {
    print(response.notification.request.content.userInfo)
    // call completion handler
    completionHandler([.alert, .badge, .sound])
    }
    }

    View Slide

  15. ࣮૷ (Message Handling)
    // ௨஌։෧࣌ͷॲཧ (ϑΥΞάϥ΢ϯυɺόοΫάϥ΢ϯυڞ௨)
    extension AppDelegate: UNUserNotificationCenterDelegate {
    public func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler:
    @escaping () -> Void) {
    print(response.notification.request.content.userInfo)
    // call completion handler
    completionHandler()
    }
    }

    View Slide

  16. ΍Δ͜ͱຖճಉ͡Ͱ͸ʁ

    View Slide

  17. ϥΠϒϥϦԽ
    • Tsuchi (https://github.com/miup/Tsuchi)
    • TypeSafe ʹ Payload Λѻ͑Δ
    • τϐοΫʹ΋ରԠ

    View Slide

  18. ࢖͍ํʢPayload)
    struct PushNotification: PushNotificationPayload {
    let hoge: String
    let hige: String
    let aps: APS?
    }

    View Slide

  19. ࢖͍ํʢinitializeʣ
    class NotificationHandler {
    static let shared = NotificationHandler()
    private init() {
    // initialize your Tsushi settings (ىಈதͰ΋όφʔग़͔͢Ͳ͏͔)
    Tsuchi.shared.showsNotificationBannerOnPresenting = true
    Tsuchi.shared.didRefreshRegistrationTokenActionBlock = { token in
    // save token to your Database
    }
    Tsuchi.shared.subscribe(PushNotification.self) { result in
    switch result {
    case let .success((payload, mode)):
    print("reiceived: \(payload), mode: \(mode)")
    case let .failure(error):
    print("error: \(error)")
    }
    }
    }
    }

    View Slide

  20. ࢖͍ํʢRegistrationʣ
    extension NotificationHandler {
    func register() {
    Tsuchi.shared.register { granted in
    if granted {
    print("success registration")
    } else {
    print("failure registration")
    }
    }
    }
    func unregister() {
    Tsuchi.shared.unregister {
    print("unregister")
    }
    }
    }

    View Slide

  21. ࢖͍ํʢTopicʣ
    enum Topic: TopicType {
    case userAction(userID: String)
    var rawValue: String {
    switch self {
    case .userAction(let userID):
    return "user-action-\(userID)"
    }
    }
    }
    extension NotificationHandler {
    func subscribe(topic: Topic) {
    Tsuchi.shared.subscribe(toTopic: topic)
    }
    func unsubscribe(topic: Topic) {
    Tsuchi.shared.unsubscribe(fromTopic: topic)
    }
    }

    View Slide

  22. ۩ମతʹ
    • ΞϓϦىಈ࣌ʹ NotificationHandler Λ init
    • Ϣʔβʔ࡞੒ͨ͠Β Registration
    • ϑΥϩʔ࣌ʹ subscribe to topic
    • ΞϯϑΥϩʔ࣌ʹ unsubscribe from topic

    View Slide

  23. ࣮ࡍͷίʔυʢRegistrationʣ
    let user = Firebase.User()
    user.save { (ref, error) in
    guard let _ = ref else { return }
    NotificationHandler.shared.register()
    }

    View Slide

  24. ࣮ࡍͷίʔυʢTopicʣ
    extension Firebase {
    class User: RootObject {
    ...
    func follow(_ user: Firebase.User) {
    self.followee.insert(user)
    user.follower.insert(self)
    NotificationHandler.shared
    .subscribe(topic: .userAction(userID: user.id))
    }
    func unfollow(_ user: Firebase.User) {
    self.followee.remove(user)
    user.follower.remove(self)
    NotificationHandler.shared
    .unsubscribe(topic: .userAction(userID: user.id))
    }
    }
    }

    View Slide

  25. ࣮ࡍͷίʔυʢCloud Functionsʣ
    functions.database.ref(root/v1/post/{postID}).onCreate(async event => {
    const firPost: firebaseModel.Post = event.data.val()
    let user = await admin.database()
    .ref(`root/v1/user/${firPost.userID}`)
    .once(‘value’)
    .then(snap => snap.val())
    const payload = {
    notification: {
    title: '৽͍͠౤ߘ͕͋Γ·ͨ͠',
    body: `${user.name}͕৽͍͠౤ߘΛ͠·ͨ͠`
    }
    }
    admin.messaging()
    .sendToTopic(`user-action-${firPost.userID}`, payload)
    }

    View Slide

  26. σϞ

    View Slide