【Firebase】Cloud Functions for Firebase to Firebase Realtime Databaseの接続実験を行っていく

はじめに

こんにちは、がんがんです。
前回の記事ではFirebase CLI環境をDockerにて構築し、Hello Worldを行っていきました。
gangannikki.hatenadiary.jp

今回はCloud Functions for Firebase(nodejs:8)からFirebase Realtime Databaseの接続実験を行っていきました。

目的

  • Cloud Functionsの実験を行う
  • FunctonsからRealtime Databaseへの書き込み実験

参考

GoogleさんのものはCodelabにコードがあることが多いのでとても助かります。

Codelabのコード
codelabs.developers.google.com

firebase公式のgithub
github.com

firebase公式のドキュメント
firebase.google.com


今回はGitHubのコードとドキュメントをベースにしながら実験を行っていきます。

前回からの変化(Node.jsのバージョン変更)

以前の記事からの変化としては、nodejsのバージョンを10→8と変更しました。Dockerfileの変更は下記の通りです。
差分を下記に載せておきます。

Dockerfile
- FROM node:10.18-alpine
+ FROM node:8

WORKDIR /app

- RUN apk update && \
+ RUN npm install -g npm \
    npm install -g firebase-tools \
    && rm -rf /var/lib/apt/lists/*

index.jsの編集

デプロイするindex.jsの編集を行います。基本的には本家のコピペですので、綺麗なコードはそちらを参照ください。
プログラムとしては小文字をすべて大文字にするという関数です。

'use strict';

// [START all]
// [START import]
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Cloud Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
// [END import]

// [START addMessage]
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
// [START addMessageTrigger]
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // [END addMessageTrigger]
    // Grab the text parameter.
    const original = req.query.text;
    // [START adminSdkPush]
    // Push the new message into the Realtime Database using the Firebase Admin SDK.
    const snapshot = await admin.database().ref('/messages').push({original: original});
    // Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
    res.redirect(303, snapshot.ref.toString());
    // [END adminSdkPush]
  });
  // [END addMessage]
  
  // [START makeUppercase]
  // Listens for new messages added to /messages/:pushId/original and creates an
  // uppercase version of the message to /messages/:pushId/uppercase
  exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
      .onCreate((snapshot, context) => {
        // Grab the current value of what was written to the Realtime Database.
        const original = snapshot.val();
        console.log('Uppercasing', context.params.pushId, original);
        const uppercase = original.toUpperCase();
        // You must return a Promise when performing asynchronous tasks inside a Functions such as
        // writing to the Firebase Realtime Database.
        // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
        return snapshot.ref.parent.child('uppercase').set(uppercase);
      });
  // [END makeUppercase]
  // [END all]

プロジェクトの実行およびfunctionのデプロイ

いつも通り、Docker Composeで起動していきます。firebase login:ciの設定をしてないので、今回も以前のようにログインしてます(次回は設定済みだと思います)。

(host os) $ docker-compose up -d && docker-compose exec app bash
(docker) $ firebase login --no-localhost
(docker) $ firebase deploy 

実行結果の確認

上手くデプロイできたかを確認してみます。ドキュメントを参考に、Firebaseコンソールで表示されたURLにアクセスしてみます。

https://<表示URL>?text=uppercasemetoo

FirebaseコンソールよりRealtime Databaseにアクセスしてみます。下記のような画面が表示されていれば問題ないです。

f:id:gangannikki:20200225114820j:plain
Databaseで確認できればOKです

メモ1:firebase deployのオプション

p# firebase deploy -h
Usage: firebase deploy [options]

deploy code and assets to your Firebase project

Options:
  -p, --public <path>      override the Hosting public directory specified in firebase.json
  -m, --message <message>  an optional message describing this deploy
  -f, --force              delete Cloud Functions missing from the current working directory without confirmation
  --only <targets>         only deploy to specified, comma-separated targets (e.g. "hosting,storage"). For functions, can    
                           specify filters with colons to scope function deploys to only those functions (e.g. "--only       
                           functions:func1,functions:func2"). When filtering based on export groups (the exported module     
                           object keys), use dots to specify group names (e.g. "--only
                           functions:group1.subgroup1,functions:group2)"
  --except <targets>       deploy to all targets except specified (e.g. "database")
  -h, --help               output usage information

おわりに

今回はCloud FunctionsからFirebase Realtime Databaseへの接続実験を行いました。
functionsのデプロイ方法やデプロイ後の様子などを体感出来てよかったです。次回はCloud Firestoreへアクセスしていきます。

[追記] 次回の記事はこちらです。
gangannikki.hatenadiary.jp