備忘録です。
自動生成されたドキュメントの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上の任意の値が書き換わるようにする。
#GoogleフォームのスクリプトエディタでGASを書く
ライブラリを追加
GASのライブラリにFirestoreとつないでデータを書き込むためのライブラリを追加する。
今回は「FirestoreApp」というライブラリを使用する。
https://github.com/grahamearley/FirestoreGoogleAppsScript
左側の「ライブラリ」から
1VUSl4b1r1eoNcRWotZM3e87ygkxvXltOgyDZhixqncz9lQ3MjfT1iKFw
というIDで検索し、「FirestoreApp」の最新バージョンを追加。
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"にしてローカルに保存。
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」を実行する
という条件を追加する。
参考にさせていただいた記事🙏:
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
もっと賢いやり方ありましたら是非教えてください🙏