質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.21%

Firebase Cloud Messagingと CloudFunctionsでのPush通知がうまくいかない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 943

okazaki0608

score 50

現在、Flutterでアプリを作っており、そのクライアントアプリのButtonを押すと、特定のtoken目掛けてPush通知を送るようなロジックをCloudFunctionsで作っています。

実装していざ押してみると、500 Server Errorが発生しているようでうまくPushが飛びませんでした。
以下、Flutter側とServer側の実装を記します。

Flutter

final HttpsCallable callable = CloudFunctions.instance
        .getHttpsCallable(functionName: 'sendMessage')
          ..timeout = const Duration(seconds: 30);



onPressed: () async {
              final HttpsCallableResult result = await callable.call(
                <String, dynamic>{
                  // 各パラメータに値が入っていることはログ出力して確認済み
                  'registerUser': book.data['registerUser'],
                  'displayName': displayName,
                  'bookTitle': book.data['title'],
                },
              );
            }

CloudFunctions(Node.js)

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

const db = admin.firestore();
const fcm = admin.messaging();

// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.sendMessage = functions.https.onCall(async (data, context) => {
  const registerUserId = data.registerUser;
  const registerUserToken = db
    .collection("users")
    .doc(registerUserId)
    .get("token");
  const sender = data.displayName;
  const bookTitle = data.bookTitle;

  const payload = {
    notification: {
      title: "てすと",
      body: `${sender} : ${bookTitle} `,
      // icon: "your-icon-url",
      // click_action: "FLUTTER_NOTIFICATION_CLICK", // required only for onResume or onLaunch callbacks
    },
  };

  return fcm.sendToDevice('registerUserToken', payload);
});

原因切り分けとして、Flutter-CloudFunctionsでデータの受け渡しがうまくいっていない可能性があると考え、registerUserTokenをベタがきで書いてみるとPushが飛ぶようになりました。

CloudFunctionsとNode.jsがわかっておらず、初歩的な質問で申し訳ないのですが、この値の受け渡し方のどのあたりに問題があるのでしょうか。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

ざっとコードをみた感じですが...

以下のトークン取得は、非同期ですが、awaitしていない気がします

  const registerUserToken = db
    .collection("users")
    .doc(registerUserId)
    .get("token");

以下のプッシュ通知の第一引数が文字列になっており、変数渡せてない気がします

  return fcm.sendToDevice('registerUserToken', payload);

console.log とかで各変数の値が適切なものになっているか調べると原因がわかると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/05 13:54

    registerUserTokenが文字列になっている件は、質問する際に掲載用にソースを加工した際に誤ってクォートで囲っていました。

    awaitの件、たしかに抜けていました。どうもありがとうございます。
    加えて、以下のように修正し、Flutterとのデータの授受に成功しました。

    ```
    const registerUserTokenRef = await db
    .collection("users")
    .doc(registerUserId)
    .get();
    const registerUserToken = registerUserTokenRef.data()["token"];
    ```

    どうもありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る