本篇要解決的問題
以前的筆記文有用到 Google Apps Script + Firebase 時,都是用 Realtime Database。但之前就覺得 Google 主力是開發 Cloud Firestore,就想知道該怎麼用 GAS 來讀寫 Firestore 的資料。
搜尋了一下後,找到了這篇:FirestoreGoogleAppsScript
本文就是參考這篇來進行,比較像是看著文件然後一步步跟著實作。
以下將 Google Apps Script 簡稱「GAS」,將 Firebase Cloud Firestore 簡稱「Firestore」。
如果是想不透過 GAS 來使用 Firestore 的功能,可另行參考這篇:
Firebase Cloud Firestore 常用功能筆記
安裝程式庫
新增完 GAS 的檔案後,點擊導覽列上的「資源 > 程式庫」:
在「Add a library」上輸入:
1VUSl4b1r1eoNcRWotZM3e87ygkxvXltOgyDZhixqncz9lQ3MjfT1iKFw
按下「新增」,會看見上面的列表多了一個「FirestoreApp」:
接著我們要選擇版本,直接選最新的版本就行,寫這篇時最新的是 33,這邊就選 33。
選完版本後按下「儲存」,這步就完成了。
開啟 Cloud Firestore
為了能夠使用 Cloud Firestore,我們必須先把 Firestore 給開啟。
進到 Firebase 的頁面,選好我們的專案後,點擊左側選單的「Cloud Firestore」,會看見這個頁面:
點擊「建立資料庫」,會出現要用什麼模式來啟動:
下一段我們會取得密鑰,因此這邊可以直接選用「以正式版模式啟動」。
按下繼續後,會出現要將資料放在哪一個地區:
選好地區後,按下「啟用」這步便完成了。
取得密鑰
在 GAS 上使用 FirestoreApp 前,我們需要一組密鑰,App 才能透過密鑰來讀寫 Firestore。
我們先進到 Google 的頁面:Service Accounts
頁面會出現我們所擁有的 Firebase 專案,選好想使用的專案後,會看到列表,點擊上面的「Create Service Account」:
建立服務帳號有三個表單要填,第一個是基本資訊:
基本資訊要填的是:帳號名稱、帳號 ID、帳號描述。
帳號描述非必填,這一張表填寫完就按下「Create」,會進到第二張表:
第二張表就是要選擇這個服務帳號有什麼樣的權限,點擊「Select a role」,在輸入框輸入:
Cloud Datastore Owner
就會篩選出「Cloud Datastore Owner」,點擊後就這組帳號就加入可以讀寫 Firestore 的權限。
按下「Continue」就會進到第三張表,這張表我們什麼都不用做,直接按下「Done」即可。
按完「Done」,會回到列表,新增成功的話便會看到我們剛剛新增的帳戶:
接著點擊右邊的點點點,會出現小選單,選擇「Create key」:
點擊完會出現一個燈箱詢問要下載的格式:
選擇「JSON」後按下「CREATE」,便會下載一個 JSON 檔,打開來會有這些內容:
我們需要其中三個值:project_id、private_key、client_email。
GAS 程式碼部份
初始化
我們先把 firestore 設成變數,後續才可以呼 function,初始化的程式碼如下:
var email = 'JSON檔中的 client_email'; var key = 'JSON檔中的 private_key'; var projectId = 'JSON檔中的 project_id'; var firestore = FirestoreApp.getFirestore(email, key, projectId);
project_id、private_key、client_email,這三個就是我們在上一步最後下載的 JSON 檔案中有的,直接 copy 貼上,初始化就完成。
讀取資料
文件上的範例是這樣:
// 讀 collection 的所有 document var allDoc = firestore.getDocuments("collection名稱"); // 讀 collection 中的部份 document var someDoc = firestore.getDocuments("collection名稱", ["document名稱1", "document名稱2"]); // 讀 document 中的資料 var doc = firestore.getDocument("collection名稱/document名稱");
回傳的資料會含有像是「更新時間」、「路徑」……等等的,實際上不太常用到的資訊,因此 August 這邊整理了讀取資料的部份,並寫成 function:
本篇在 Firestore 上的資料如下:
用 getCollection
把取到的資料 Logger.log
如下:
// code var data = getCollection('col'); Logger.log(data); // output [{col/doc1={name=August1}}, {col/doc2={name=August2}}]
用 getDocument
把取到的資料 Logger.log
如下:
// code var data = getDocument('col/doc1'); Logger.log(data); // output {name=August1}
寫入資料
寫入資料有二個 function:create
、update
。
差別在於,create 可以自動生成一段亂數當作 document 的 ID。
create
如果想讓 document 是亂數,程式碼如下:
var data = { "name": "test!" } firestore.createDocument("DemoCollection", data);
執行後,就會看見 Firestore 新增了我們的 data:
如果在 createDocument
時,路徑已指定了 document 的名稱,那就不會有亂數出現,比方我們程式碼改成以下:
var data = { "name": "test!" } firestore.createDocument("DemoCollection/MyDocName", data);
執行後 Firestore 就會新增資料如下:
另外要注意的是,createDocument
只能用來新增,如果 Firestore 在路徑上已存在資料,就會報錯。
update
update 的程式碼如下:
firestore.updateDocument("collection的名稱/document的名稱", data, true);
Update 一定要指定 document 的名稱,不然會報錯。
第三個的 true
,是指要不要只更新有異動的部份?true 就是只更新有異動的欄位、false 就是全部覆蓋。
比方我們原本的欄位是:
name: "August"
age: 18
而我們想更新的資料是:
age: 20
是 true
的話,欄位更新後會是:
name: "August"
age: 20
是 false
的話,欄位更新後會是:
age: 20
為 false
時因為整批被蓋掉,因此只會剩下我們之後更新上去的值。
刪除資料
firestore.deleteDocument(collection的名稱/document的名稱);
無法直接刪掉整個 collection,一次最多是刪掉一個 document。
完整的讀取、寫入、刪除程式碼
為了之後別的案子可以直接使用 GAS + Firestore,這邊把讀寫刪整理成 function,方便以後取用:
關於排序、搜尋
文件上也有排序、搜尋,因為覺得之後想做的功能不會用到,本篇就不列出,可自行觀看文件:FirestoreGoogleAppsScript。
謝謝您的教學。
您文中「初始化」的 email 與 projectId 註釋寫反囉。
真的耶,已修改,感謝你。