IoT CoreからCloud Functions経由でFirestoreにデータを追加する

# はじめに

[Firebase](https://firebase.google.com/?hl=ja)はモバイルフロントエンドを作るのに大変便利なプラットフォームなので、IoT的なアプリをFirebaseにホストしたくなるものである。

GCPには[IoT Core](https://cloud.google.com/iot-core/?hl=ja)というデバイスとクラウドをつなぐプラットフォームもあるので、IoT CoreからMQTTかなんかでデータをパブリッシュしてFirebaseでPub/Subできればデバイスのデータを可視化するアプリなんかはすぐできそう感じがする。しかもほぼ無料で。

というわけで、いままで試してきた [Firebase Cloud Firestoreを使ってみる](https://qiita.com/bathtimefish/items/164d2b0cd268f209db9b) 、 [Google Cloud IoT Coreを使ってみる](https://qiita.com/bathtimefish/items/095838cf2f99c2a2d2df) 、 [Cloud Functions で IoT CoreをPubSubしてみる](https://qiita.com/bathtimefish/items/a93400f4bc79330f23ae) を参考にIoT CoreからCloud Functionsを経由してFirestoreにデータを追加してみる。

# やってみる

[Cloud Functions で IoT CoreをPubSubしてみる](https://qiita.com/bathtimefish/items/a93400f4bc79330f23ae) で作った`btf-test-iot` 関数を更新する。まず、Functionsのコンソールから 該当関数をクリックする。

![スクリーンショット 2018-03-24 12.06.29.png](https://qiita-image-store.s3.amazonaws.com/0/61995/3590e4ad-fd26-9808-7725-8097de455bc1.png)


編集 をクリック。

![スクリーンショット 2018-03-24 12.07.08.png](https://qiita-image-store.s3.amazonaws.com/0/61995/fe34b2a3-68c4-ab3e-b2f8-4f0ec01a3fa4.png)


関数の詳細が開く。インラインエディタの `index.js` を以下のように変更する。

`[SERVICE_ACCOUNT_JSON]` は [Firebase Cloud Firestoreを使ってみる](https://qiita.com/bathtimefish/items/164d2b0cd268f209db9b) でダウンロードしたサービスアカウントのJSONファイル内のJSONを記載する。

```index.js
/**
 * Triggered from a message on a Cloud Pub/Sub topic.
 *
 * @param {!Object} event The Cloud Functions event.
 * @param {!Function} The callback function.
 */

const admin = require('firebase-admin');

const serviceAccount = [SERVICE_ACCOUNT_JSON]

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

var db = admin.firestore();

exports.subscribe = (event, callback) => {
  // The Cloud Pub/Sub Message object.
  const pubsubMessage = event.data;

  // We're just going to log the message to prove that
  // it worked.
  var message = Buffer.from(pubsubMessage.data, 'base64').toString();
  
  var docRef = db.collection('messages').add({
      "message": message,
      "created": Date.now()
  }).then(function(docRef) {
    console.log("Document written with ID: ", docRef.id);
  }).catch(function(error) {
    console.error("Error adding document: ", error);
  });
  
  // Don't forget to call the callback.
  callback();
};
```

インラインエディタの package.json タブをクリックする。

![スクリーンショット 2018-03-24 12.16.33.png](https://qiita-image-store.s3.amazonaws.com/0/61995/8cb03ebb-0b7a-150b-195d-d9c5faea5411.png)


package.json を以下のように変更する。

```package.json
{
  "name": "sample-pubsub",
  "version": "0.0.1",
  "dependencies": {
    "firebase-admin": "^5.10.0"
  }
}
```

変更したら、保存 をクリックして関数をデプロイする。

[Cloud Functions で IoT CoreをPubSubしてみる](https://qiita.com/bathtimefish/items/a93400f4bc79330f23ae) で作成したIoT Core パブリッシュ用のコードを実行する。

```
node index.js
```

実行後しばらくしてFunctionsのログを確認するとFirestoreから追加したドキュメントのIDが表示されている。

![スクリーンショット 2018-03-24 12.24.52.png](https://qiita-image-store.s3.amazonaws.com/0/61995/23b44910-82c8-4c92-f3c0-c9a7939e80fe.png)


FirebaseコンソールのDatabaseを確認する。Functionsからデータがリアルタイムに追加されているのが確認できる。

![スクリーンショット 2018-03-24 12.27.02.png](https://qiita-image-store.s3.amazonaws.com/0/61995/19b75c45-2078-7514-afcf-a14d7568875b.png)


# まとめ

[firebase-admin](https://www.npmjs.com/package/firebase-admin) をCloud Functionsで実行することでFirebaseに簡単にデータを追加できる。ここまでできたら Firebase側で firebase-admin や Cloud Functions for Firebaseでデータを参照すればいい。

次は Cloud Functions for Firebase の Firestore triggerで追加されたデータを取得してみようと思う。