はじめに
現在、個人開発してるアプリでチャットみたいな仕組み(サーバの話)を作っててFirebase Databaseにデータが追加されたら指定ユーザやトピックにプッシュ通知を配信するっていうのをできないかなぁって思ってやってみました。
元ネタは Firebase で iOS クライアントからプッシュ通知を送る です。
私はNode.jsが(デプロイ実装)できないのでPythonでしました。
環境
- Python 3.5.2 (3.6を入れ忘れてました。)
- Xcode8.2.1
- iOS10.2
iOS側の準備
プッシュ通知準備
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にデータを追加する
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を監視するコード
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
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場所
(プライバシーは保護させてください!!)
監視コードの説明
Pythonパッケージは Pyrebase
と python-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