こんにちは。 いるべさんです。
Firebaseを使ってユーザ間の通知を行う実装をしていたとき、馴染みのある「ティロリン♪」ってやつしか使い方分からなくて困っていた。
通知音をインポートして再生するやり方はよく見かけた。
が、めんどくさがり屋ないるべさんはそんなことしたく無い!!!
今回はAudioToolbox使って通知音とする様にした。
ただ、こんなことしなくてもちゃんとしたやり方がありそう。
構成仕様
構成としては、ユーザがCloud FireStoreにデータを突っ込んだらそれをClound Functionsが検知して購読しているユーザに通知を送るよくある普通の実装。
通知を受け取ったら通知情報からsoundの項目を引っ張ってきてAudioToolboxに再生してもらう簡単仕様。
なので、通知を送るFunctionsのpayloadのsoundの項目にSoundSystemIdの値、もしくは通知ごと、ユーザごとに通知音を変えたいならその識別子を入れておく。
実装
Functions
まずはCloud Functionsの関数を作成する。大事そうなところだけピックアップして記載しておく。
今回の話の肝になるのはpayloadのsound。
ここにAudioToolboxに通用するSystemSoundIdを入れておく。
exports.sendNotifications = functions.firestore.document('/notifications/{userId}/messages/{messageId}').onCreate((snapshot, context) => {
~~ 省略 ~~
var payload = {
notification: {
title: data.username,
body: data.detail,
badge: "1",
sound: "1020"
}
};
~~ 省略 ~~
return admin.messaging().sendToTopic(topic, payload, options)
.then(function(response) {
return console.log(response);
})
.catch(function(error) {
return console.log(error);
});
通知を受け取る側
まぁ何も難しいことはしてなくて、通知から必要な情報取り出してAudioToolboxに突っ込んでいるだけ。
普通にやる場合はcompletionHandlerに.soundを入れる形なのでそのやり方で今回と同じ様なことができたらなぁと思う。ご存知の方、ぜひ教えてください!
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
if let aps = userInfo["aps"] as? [String: Any] {
let soundId: SystemSoundID = SystemSoundID(aps["sound"] as! String) ?? 1007
AudioServicesPlaySystemSound(soundId)
}
completionHandler([.alert, .badge])
}
これでユーザが通知を受け取ったとき、今回で言えば設定したid:1020が鳴るというわけです。
やり方が正しいかは分からないけど思い通りの実装ができたので今のところはヨシ!!!