PUROGU LADESU

ポエムがメインのブログです。

【Firebase】Functionsでリモート通知を送信

準備

nodejs

バージョンはfunctionsでは14がベータっぽいので一応12にしておく。

brew install nodenv
nodenv install -l
nodenv install 12.20.1
functions
firebase init firestore 
// プロンプトに答える
// めんどくさい場合はeslintを入れないほうが良い

ESLintの調整。
prettierとの競合をなくすのと、新しいJSへの対応。

npm install eslint-config-prettier
npm install babel-eslint
アップロード

firebase consoleに表示される。ログも見れる。

firebase deploy --only functions

Functionsを実装

Firestoreへのデータ登録をトリガーにFunctionを発動させます。
端末を指定して通知を送るのでデバイストークンをDBに入れておいて取ってくる必要があります。
デフォルトではus-centralにデプロイされてしまったのでasia-northeast1を指定しています。(そもそもの初期設定がおかしかったのか?記憶がない。)

// 東京リージョンへデプロイする
const functions = require("firebase-functions").region("asia-northeast1");

const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
const msg = admin.messaging();

// ユーザーの取得
const getUser = async (userId) => {
  try {
    const docRef = db.collection("Users").doc(userId);
    const snapshot = await docRef.get();
    if (!snapshot.exists) {
      console.log("Not found");
      return { error: "Not found" };
    } else {
      console.log(snapshot.data());
      return snapshot.data();
    }
  } catch (e) {
    console.log(e.message);
    return { error: e.message };
  }
};

// 通知の送信
const sendRemoteNotification = async (deviceToken, notification, data = {}) => {
  // メッセージ
  const message = {
    notification: notification,
    data: data,
    token: deviceToken,
  };
  // 送信処理
  msg
    .send(message)
    .then((response) => {
      // Response is a message ID string.
      console.log("Successfully sent message:", response);
    })
    .catch((error) => {
      console.log("Error sending message:", error);
    });
};

// FirestoreのNotificationにデータが作成されたら通知送信
exports.onCreateNotification = functions.firestore
  .document("/Users/{userId}/Notifications/{notificationId}")
  .onCreate(async (snap, context) => {
    // console.log(context.params);
    const userId = context.params.userId;
    console.log(snap.data());
    const data = snap.data();

    // ユーザー情報からデバイストークンを取得
    const user = await getUser(userId);
    // 通知の中身
    const notification = {
      title: data.title,
      body: data.content,
    };
    // 通知の送信
    sendRemoteNotification(user.deviceToken, notification);
  });

おまけ

exports.queryTest = functions.https.onRequest((request, response) => {
  console.log(request.query);
  response.send(request.query);
});