26
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSアプリからFirebase Cloud Messaging経由でプッシュ通知を送る

Last updated at Posted at 2017-01-17

はじめに

現在、個人開発してるアプリでチャットみたいな仕組み(サーバの話)を作っててFirebase Databaseにデータが追加されたら指定ユーザやトピックにプッシュ通知を配信するっていうのをできないかなぁって思ってやってみました。

元ネタは Firebase で iOS クライアントからプッシュ通知を送る です。

私はNode.jsが(デプロイ実装)できないのでPythonでしました。

環境

  • Python 3.5.2 (3.6を入れ忘れてました。)
  • Xcode8.2.1
  • iOS10.2

iOS側の準備

プッシュ通知準備

AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound],
                                                  categories: nil)
    application.registerUserNotificationSettings(settings)
    application.registerForRemoteNotifications()
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // APNS登録
    #if DEBUG
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .sandbox)
    #else
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .prod)
    #endif
}

func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
    // トピックに登録
    FIRMessaging.messaging().subscribe(toTopic: "/topics/news")
}

あとのプッシュ通知をするためのhogeをやっておいてください!

Firebase Databaseにデータを追加する

Hoge.swift
class Hoge: NSObject {
    class func create() {
        let ref = FIRDatabase.database().reference()

        let data: [String : String] = ["title": "タイトル", "body": "本文"]
        ref("message").childByAutoId().setValue(data, withCompletionBlock: { (error, reference) in
            if error != nil {
                print("Success")
            } else {
                print("Failure")
            }
        }
    }
}

THE 雑ですがこんなもんでしょう

Firebase Databaseを監視するコード

requirements.txt
docutils==0.13.1
gcloud==0.17.0
googleapis-common-protos==1.5.0
httplib2==0.9.2
jws==0.1.3
lockfile==0.12.2
oauth2client==3.0.0
protobuf==3.2.0rc1
pyasn1==0.1.9
pyasn1-modules==0.0.8
pycryptodome==3.4.3
Pyrebase==3.0.27
python-daemon==2.1.2
python-jwt==2.0.1
requests==2.11.1
requests-toolbelt==0.7.0
rsa==3.4.2
six==1.10.0
app.py
import daemon
import json
import pyrebase
import requests

config = {
    # GoogleService-info.plistのAPI_KEY
    "apiKey": "API_KEY",
    "authDomain": "PROJECT_NAME",
    "databaseURL": "https://PROJECT_NAME.firebaseio.com/",
    # いらないかもしれない
    "storageBucket": "gs://PROJECT_NAME.appspot.com"
}

fcm_header = {
    'Content-type': 'application/json; charset=UTF-8',
    # このコードの下の画像を参照してください!
    'Authorization': 'key=API_KEY'
}

firebase = pyrebase.initialize_app(config)

def stream_handler(message):
    if message['data'] == None:
        return
    if message['path'] == '/':
        return

    if 'title' in message['data']:
        title = message['data']['title']
    else:
        title = '配信'

    if 'body' in message['data']:
        body = message['data']['body']
    else:
        body = ''

    payload = {'to': '/topics/news', 
               'priority': 'high', 
               'notification': {
                   'title': title,
                   'body': body,
                   'badge': 1,
                   'sound': 'default'
               }
              }

    r = requests.post('https://fcm.googleapis.com/fcm/send', headers = fcm_header, data = json.dumps(payload))
    print(r.json())

if __name__ == '__main__':
    db = firebase.database()
    dc = daemon.DaemonContext()
    with dc:
        stream = db.child("message").stream(stream_handler)

API_KEY場所

スクリーンショット_2017-01-18_0_46_34.png

(プライバシーは保護させてください!!)

監視コードの説明

Pythonパッケージは Pyrebasepython-daemon を使用させていただきました。

$ pip install pyrebase python-daemon

Firebase Databaseの /message ディレクトリを見に行ってます。

if message['data'] == None:
    return
if message['path'] == '/':
    return

ここらへんは、/message にデータがないときにエラーが起きた(?)ので例外処理です。監視コード起動時プッシュ通知を送ってくれるのにiOS側には通知は来てるけどアラートが表示がされない!っていうことがあったので入れています。

あとはサーバ側でスクリプトを実行するだけです。
ちなみに python-daemon を使用することでスクリプトをデーモン化してくれます!とてもありがたいですね!

$ python app.py

実行サンプル

Firebase Databaseサンプル

Firebase Databaseサンプル

通知結果

47ad6b91-a6cd-ff84-c153-f0abd580a820.png
26
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?