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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

1945閲覧

firebase cloud functions で処理が想定通りに機能したり、しなかったりする

RyomaD

総合スコア34

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

1クリップ

投稿2019/02/12 03:07

編集2019/02/12 03:52

なぜかわかりませんが、cloud functionsから外部apiから取得した情報をrealtime databaseへ保存する過程で、保存が成功したり、しなかったりしてしまいます。

どういうことかといいますと、

// realtime databese上でユーザが作成されたら以下が走る exports.deviceRegister = functions.auth.user().onCreate(event => { // ここでユーザuidを取得している。 const user = event.uid; console.log(user) // ここは毎回走っている console.log("1"); // 新しく作成されたユーザの/Users/${user}/deviceTokenパス以下の情報を参照、 db.ref(`/Users/${user}/deviceToken`).on("value", function(snapshot) { console.log(snapshot.val()); // 参照した情報がnullなら、 if(snapshot.val() === null){ console.log("デバイストークンが取得できていないよ") }else{ console.log("デバイストークンが取得できたよ") // Onesignalへデバイストークンを登録するためのメソッド == ここから // nullじゃなければ以下の処理が走る var request = require("request"); var options = { method: 'POST', url: 'https://hogehoge.com/api/v1/players', headers: { 'cache-control': 'no-cache', 'Content-Type': 'application/json' }, body: { app_id: '242******************3', identifier: snapshot.val(), language: 'en', timezone: -28800, game_version: '1.0', device_os: '7.0.4', device_type: 0, device_model: 'iPhone', tags: { a: '1', foo: 'bar' } }, json: true }; request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body["id"]); console.log(response); // ここが走ったり走らなかったり、 console.log("2"); // 以下の処理がrealtime databaseへ保存する処理 db.ref(`/Users/${user}/`).update({ "playerid": body["id"] }); }); return 0; }}, function(errorObject) { console.log("The read failed: " + errorObject.code); } ); // ここは毎回走っていることを確認できている console.log("3"); })

という感じで、以下の処理が走らずに終了してしまいます。

db.ref(`/Users/${user}/`).update({ "playerid": body["id"] });

しかし、処理が正常に機能することもあり訳が分からず困っております。
私の理解としては、以下処理が終了する前に

request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body["id"]); console.log(response); // ここが走ったり走らなかったり、 console.log("2"); // 以下の処理がrealtime databaseへ保存する処理 db.ref(`/Users/${user}/`).update({ "playerid": body["id"] });

以下の処理が終了しているため上記の処理が動作しないと考えております。

exports.deviceRegister = functions.auth.user().onCreate(event =>

なぜ起こるものなのか、ご存知の方いましたらご教授のほどよろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakajika

2019/02/13 09:07

Promiseの使い方は理解されていますか?そちらから勉強してはいかがでしょう
RyomaD

2019/02/13 11:38

アドバイスありがとうございます。 おっしゃる通りです。 Promiseの使い方もいくつか調べてみたものの、 未だしっくり来なかったので今はsetTimeoutでなんとか想定の処理はできています。(ダサいですが) なのでPromiseの使い方を勉強しつつ、 今回のようなケースでベストな使い方をご存知の方から一言をお待ちしてみようと思います。 繰り返しになりますがアドバイスありがとうございます。
guest

回答1

0

ベストアンサー

Cloud Functionsでは関数の返り値としてPromiseを返すようにすることで、時間のかかる処理が完了するまで待機するようにできます。(逆にいえば、正しくPromiseで返さないと、処理の途中でもFunctionsのインスタンスが終了する可能性があります。これが問題の原因です)

ドキュメント: https://firebase.google.com/docs/functions/terminate-functions?hl=ja

ご質問のように複数の処理を順番に行いそれらを待機させたい場合にはPromiseをチェーンしていけばOKです。まずはPromiseについて勉強してみてください。

投稿2019/02/13 13:43

編集2019/02/13 13:56
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問