4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

google formで回答したらGASを使ってfirebaseに連携し、自動生成したIDを持つドキュメントのデータを書き換える

Last updated at Posted at 2021-04-06

備忘録です。

自動生成されたドキュメントのID(ランダムな文字列のID)を
ライブラリ「FirestoreApp」で取り出せなかったので、そちらについて特に残しておきたくて書いています。

つまづきポイント:

GASで今回のライブラリ「FirestoreApp」でwhereを使うところまではできたけれど、
その後、通常firebaseで書く書き方では、ランダムな文字列のIDを取り出せずに悩んだ。

※通常のfirebaseで使う「where」を使った書き方では、
自動生成されたドキュメントのID(ランダムな文字列のID)を取り出せなかった。

今回は:Cloud Firestoreの中のコレクションのドキュメントIDを自動生成している

1)Cloud Firestoreの中に「hoges」コレクションが存在する。
2)hogesコレクションの中には『IDが自動で割り振られたランダムな文字列』のドキュメントが多数ある。
3)hogesコレクション内の各ドキュメントはキー「hogeID」で、値を持っている。

やりたいこと:

google formで送信し「fugaID」として受け取った値と、
自動生成されたランダムなIDをもつ各ドキュメントの中にある「hogeID」の値が一致した時に、
そのドキュメント内にあるキー「answerd1」「answerd2」などの値を書き換えたい。

#Google formを準備
googleフォームを作成する。
https://www.google.com/intl/ja_jp/forms/about/

作成したら
右上の「…」から「スクリプトエディタ」を開く。

※スプレッドシートとの連携はこの記事には書かない。他の記事が沢山あるので割愛。
 今回はフォームでの送受信が発生した時に、firebase上の任意の値が書き換わるようにする。

スクリーンショット 2021-04-06 10.59.51.png

#GoogleフォームのスクリプトエディタでGASを書く

ライブラリを追加

GASのライブラリにFirestoreとつないでデータを書き込むためのライブラリを追加する。
今回は「FirestoreApp」というライブラリを使用する。
https://github.com/grahamearley/FirestoreGoogleAppsScript

左側の「ライブラリ」から

1VUSl4b1r1eoNcRWotZM3e87ygkxvXltOgyDZhixqncz9lQ3MjfT1iKFw

というIDで検索し、「FirestoreApp」の最新バージョンを追加。

スクリーンショット 2021-04-06 10.55.05.png
スクリーンショット 2021-04-06 10.55.44.png
スクリーンショット 2021-04-06 10.55.56.png

firebaseとの連携

firebaseと連携するための情報をGASに記載する。

Google Service Accountsからキーを作成して取得

Google Service Accounts page の「サービスアカウント」から
https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts

1)Firebaseのプロジェクトを選択
2)「サービスアカウントを作成」
3)サービスアカウント名、サービスアカウントIDを入力 -> 作成
4)ロール -> 「Cloud Datastore オーナー」を選択 -> 続行
5)ユーザーロール、管理者ロールは特に設定しなくてもOK -> 完了
6)作成したサービスアカウントから「鍵を作成」-> キーのタイプは"JSON"にしてローカルに保存。
スクリーンショット 2021-04-06 12.54.38.png

DLしたキーのjsonファイルから必要な情報をGASに書き込む

使うのは先ほどDLしたキーの中の
project_id private_key client_emailの3つ。

これらをgoogle formのスクリプトエディタに下記のように書き込む

// CloudFirestoreで認証する為の情報
function firestoreDate() {
  var dateArray = {
    'email': 'xxxxxxxxxxxx@xxxxxxxxxxxxxx',
    'key': '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxx\n-----END PRIVATE KEY-----\n',
    'projectId': 'xxxxxxxxxxxxxxxxxxx'
  }
  return dateArray;
}

フォームから送られてきた回答の文字列と、コレクション内の各ドキュメント内の「任意のキー」の「値」が一致したら、ドキュメントのID(ランダムに生成された文字列ID)を取得→そのドキュメント内の「別のキー」の「値」を変更

続けて先ほど書いた firestoreDate の下に、
下記のように「フォームが送信されたら実行したいスクリプト」を記載する。

async function submitForm(e){
  var itemResponses = e.response.getItemResponses();
  // ここにフォームから取得したい回答の値が入る。今回は仮で数字が入る。
  // フォームの質問の1つめの値が入る。
  const num = itemResponses[0].getResponse(); 
  // ここにフォームから取得したい回答の値が入る。今回は仮でID(文字列)が入る。
  // フォームの質問の2つめの値が入る。
  const fugaID = itemResponses[1].getResponse();

  // CloudFirestoreの認証。(上で記載したfirestoreDateを実行している。)
  var dateArray = firestoreDate();
  var firestore = FirestoreApp.getFirestore(dateArray.email, dateArray.key, dateArray.projectId);

  // fugaIDと一致するdocIDの取得
  /* 
  ここでつまずいた。
  通常のwhereの書き方で書けない。
  フォームから送られてきた回答の文字列と、IDが自動生成されているドキュメントの「任意のキー」の「値」が一致したら、
  「ドキュメントのID(自動生成された文字列)」を取得する。
  ※splitで返ってきた文字列をバラバラにして最後尾につくIDの文字列を取得した。
  */
  const ref = await firestore.query('hoges').Where('hogeId', '==', fugaID).Execute();
  const splitText = ref[0].name.split('/')
  const splitLenght = ref[0].name.split('/').length
  const docId = splitText[splitLenght - 1]
  console.log('docId',docId);

  // 更新するobjectのキー
  const answerdNum = `answerd${num}`;

  // 更新するデータ
  /* 
  今回はドキュメント内にある「answerd1」「answerd2」などの値をtrueにする。
  */
  const data = {
    [answerdNum] : true
  }

  // CloudFirestoreをドキュメント更新
  firestore.updateDocument(`hoges/${docId}`, data, true);
}

####追記: google formの質問の値から、回答の値をとってくる場合はこんな感じ

let num="";
let fugaID="";
var itemResponses = e.response.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
  var itemResponse = itemResponses[i];
  var question = itemResponse.getItem().getTitle();
  var answer = itemResponse.getResponse();
  if (question === '質問に入れた文字列'){
    num = answer;
  }
  if (question === '質問に入れた文字列'){
    fugaID = answer;
  }
}

何故かfor内のvarはvarじゃないと動かなかった…何故。

「フォームが送信されたら実行する」という条件を追加する

google formのスクリプトエディタの左の時計のアイコンから、
フォームが送信されたら「submitForm」を実行する
という条件を追加する。

スクリーンショット 2021-04-06 13.30.53.png


参考にさせていただいた記事🙏:

GAS(Google Apps Script)でCloud Firestoreを利用する時のメモ
https://qiita.com/PmanRabbit/items/a76b9bc5a9d0239c9f78

【書籍管理シリーズ】GASとFireBase(Firestore)を連携させるよ!
https://qiita.com/h_plum/items/f6ba16931f955d33158e

GAS:SpreadSheetに登録したデータをFirestoreに送信する
https://qiita.com/masa-321/items/86e356b02dcf5b840595


もっと賢いやり方ありましたら是非教えてください🙏

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?