繋がらないマッチングプラットフォーム「FLAPTALK」を運営する株式会社OneSmallStepの@_takeshi_24です。
この記事は「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして、連載していきます。
Nuxt.jsとFirebaseなどを使ってWebアプリケーション開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!
今回はアプリケーションにプッシュ通知を送るための、Firebase Cloud Messagingについて説明します。
Webアプリケーションにもプッシュ通知可能ですが、iOSのWebアプリケーションは対象外になります。
今回は、RealtimeDatabase、Firestoreの更新をトリガーに、CloudFunctionsの関数を実行し、特定のユーザーにCloudMessagingでプッシュ通知を送る方法について記載します。
はじめに
こちらの記事は、「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして連載していますので、「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」の過去の記事もご覧ください。
CloudMessagingの準備はこちら「Nuxt.jsアプリにFirebase Cloud Messagingでプッシュ通知」に記載していますので、CloudMessagingの準備がまだの方は、まずこちらの記事で準備をお願いします。
##FirestoreをトリガーにCloudFunctions実行
まずは、Firestoreのデータが更新されたら、特定のユーザーにプッシュ通知を送る処理について説明していきます。
###トリガーのもととなるFirestore更新の画面
まずは、トリガーを発生させるFirestore更新のサンプルを実装します。
メッセージ入力欄と、ユーザー一覧とユーザーごとに「プッシュ通知」ボタンを配置し、「プッシュ通知」ボタンをクリックしたら、対象のユーザー宛てにメッセージ入力欄の内容を通知するサンプルです。
画面のソースは以下の通りです。
<template>
<section class="container">
<v-text-field v-model="message"></v-text-field>
<v-row v-for="(user, key, index) in users" :key="index">
<v-col>
<p>{{ user.data.familyName }} {{ user.data.firstName }}</p>
</v-col>
<v-col>
<v-btn @click="sendMessage(user.uid)">プッシュ通知</v-btn>
</v-col>
</v-row>
</section>
</template>
<script>
import firebase from "firebase";
const db = firebase.firestore();
export default {
data() {
return {
message: "",
users: []
};
},
created() {
this.getUsers();
},
methods: {
async getUsers() {
const snapShot = await db.collection("users").get();
this.users = snapShot.docs.map(doc => {
const obj = { uid: doc.id, data: doc.data() };
return obj;
});
},
sendMessage(uid) {
db.collection("messages")
.doc(uid)
.set({
message: this.message
});
this.message = "";
}
}
};
</script>
解説していきます。
1.created()のなかで、getUsers()を実行し、Firestoreからユーザーの一覧を取得しています。データの内容は以下のような形です。FirebaseAuthenticationのUIDをusersのIDに設定していて、fcmTokenにFirebase Cloud Messagingのトークンがセットされます。
(参照:Nuxt.jsアプリにFirebase Cloud Messagingでプッシュ通知)
2.sendMessage()で、対象のuidのmessagesコレクションに、テキストのメッセージをセットします。
3.Firestoreのルールを追加します。
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow update, delete: if request.auth.uid == userId;
allow read, create: if request.auth.uid != null;
}
match /messages/{userId} {
allow create, read, update, delete: if request.auth.uid != null;
}
}
}
###更新をトリガーにCloudFunctionsを実行
messagesコレクションのデータが更新されると、それをトリガーにCloudFunctionsの関数が実行されます。
1.functionsのindex.jsに以下の関数を追加します。
exports.sendPushMessage = firestore
.document("messages/{userId}")
.onWrite(async (change, context) => {
const data = change.after.data();
const previousData = change.before.data();
// uidから通知先のユーザー情報を取得
const userRef = await admin
.firestore()
.collection("users")
.doc(context.params.userId);
const userDoc = await userRef.get();
if (userDoc.exists) {
const user = userDoc.data();
// 通知のタイトルと本文を設定
const payload = {
notification: {
title: `${user.familyName} ${user.firstName}さんへ`,
body: data.message
}
};
/// プッシュ通知を送信
if (user.fcmToken) {
admin.messaging().sendToDevice(user.fcmToken, payload);
} else {
console.error("No Firebase Cloud Messaging Token.");
}
} else {
console.error("No User.");
}
return true;
});
ここでは、onWriteを使って、ドキュメントに書き込み、更新があったときに関数を呼び出しています。
その他、以下のようなトリガーが利用できます。
| イベントタイプ | トリガー |
|:--|:--|| onCreate | ドキュメントが最初に書き込まれたときにトリガーされます。 |
| onCreate | ドキュメントが最初に書き込まれたときにトリガーされます。 |
| onUpdate | すでに存在するドキュメントの値が変更されたときにトリガーされます。 |
| onDelete | データを含むドキュメントが削除されたときにトリガーされます。 |
| onWrite | onCreate、onUpdate または onDelete がトリガーされたときにトリガーされます。 |
2.ローカルのエミュレーターではプッシュ通知は送れませんので、Firebaseにデプロイします。
$ firebase deploy
3.画面からメッセージを入力し、通知を送るユーザーの「プッシュ通知」ボタンをクリックします。
4.CloudFunctionsが起動されます。Firebaseのコンソールでログを監視できます。
5.通知が表示されます。Android端末だと、待ち受けにも通知が表示されます。
##RealtimeDatabaseをトリガーにCloudFunctionsを実行
RealtimeDatabaseでも以下の通り、Firestoreと同じようにデータの更新をトリガーにCloudFunctionsを実行できます。
exports.sendPushMessage = functions.database
.ref("/messages/{pushId}/original")
.onCreate((snapshot, context) => {
// ・・・
});
イベントタイプ | トリガー |
---|---|
onWrite | Realtime Database 内でデータが作成、更新、削除されるとトリガーされます。 |
onCreate | Realtime Database 内で新しいデータが作成されるとトリガーされます。 |
onUpdate | Realtime Database 内でデータが更新されるとトリガーされます。 |
onDelete | Realtime Database 内でデータが削除されるとトリガーされます。 |
Database トリガーより |
##最後に
この記事は「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして、連載していきます。
続きはアドベントカレンダー「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」に掲載していきます。
Nuxt.jsとFirebaseなどを使ってWebアプリケーション開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!
#advent_24のハッシュタグでフィードバックいただけると嬉しいです!