Project

General

Profile

Sử Dụng Google Forms làm NoSQL Database » History » Version 9

Lê Sĩ Quý, 08/26/2025 02:10 PM

1 1 Lê Sĩ Quý
{{TOC}}
2 2 Lê Sĩ Quý
3 4 Lê Sĩ Quý
Các sản phẩm của AKA Lab được thiết kế để tận dụng tối đa các công cụ có sẵn trong hệ sinh thái Google Workspace. Chúng tôi tập trung vào những người dùng phổ thông, không chuyên về công nghệ. Vì thế, các công cụ của AKA Lab được xây dựng dựa trên kiến thức và kỹ năng mà người dùng bình thường đã có, ví dụ như kỹ năng sử dụng Google Sheets - một trong những công cụ phổ biến nhất với người dùng máy tính tại Việt Nam. Firebase là NoSQL database hiệu suất cao, phù hợp với các ứng dụng web cần realtime nhưng lại phức tạp với người dùng phổ thông chỉ cần mục đích lưu trữ nội dung form. Các chuyên viên tại AKA Lab đã tận dụng Google Forms để làm database đơn giản phục vụ mục đích lưu trữ.
4 2 Lê Sĩ Quý
5
## Yêu cầu cơ bản
6
7
Một cơ sở dữ liệu phải hỗ trợ được 4 hành động cơ bản (gọi tắt là CRUD)
8
- Tạo mới/Create
9
- Truy vấn/Read/Query
10
- Cập nhật/Edit
11
- Xóa/Delete
12 3 Lê Sĩ Quý
13
## Cài đặt
14
15
### Tạo mới/Create
16
17
Với Google Forms bạn có thể submit dữ liệu mà không cần tương tác trực tiếp với UI của Google Forms mà thông qua URL. Cách làm xem tại đây [How to submit responses to a Google Form using Apps Script?](https://spreadsheet.dev/submit-responses-to-google-form-apps-script). Với phương thức này, chúng ta có thể tạo mới record trong Spreadsheet mà không cần phải code Apps Script, chỉ cần liên kết Google Forms với file Spreadsheet
18
19
### Truy vấn/Read/Query
20
21
Truy vấn có thể thực hiện bằng hàm QUERY với [Google Visual Query Language](https://developers.google.com/chart/interactive/docs/querylanguage)
22
23
###  Cập nhật/Edit
24
25 6 Lê Sĩ Quý
Chúng ta cần bật tùy chọn cho phép người dùng cập nhật nội dung đã submit
26
![Bật tùy chọn Allow response editing](documents-trigger-setting.png)
27
28 3 Lê Sĩ Quý
Google Forms cho phép người dùng cập nhật giá trị đã submit thông qua URL dạng **https://docs.google.com/forms/d/e/1FAIpQLSfZE4_hX35xFqo3504_SIfPB5k-4zuLme3ae_xTq4QxxsueqA/formResponse?edit2=2_ABaOnue2DOlQsXnou5viPOupaRp7ANXgcOZb8_JfewdwbaVwvbRmbjNKhzxBotFKBMKFHdQ** &entry.1745485693={Document}&entry.1408490212={ModifiedBy}&entry.95214425={ModifiedAt}&entry.988375443={IsDeleted}
29
30
Việc cần làm là lấy được giá trị editUrl của **new submission** đều này chúng ta cần đến Form Trigger, xem file *Trigger.gs* trong code project của form **Database-Documents**. Dưới đây là nội dung file *Trigger.gs*
31
32
``` javascript
33
// ⚠️ This is Form trigger. 
34
//    Open script editor from form interface
35
//    Install it wia Triggers
36
function onFormSubmit(e) {
37
    const formResponse = e.response;
38
    const itemResponses = formResponse.getItemResponses();
39
    const Id = "Id";
40
    const EditUrl = "EditUrl";
41
    const Created = "CreatedAt";
42
    const Updated = "ModifiedAt";
43
    let obj = {};
44
45
    for (const item of itemResponses) {
46
        obj[item.getItem().getTitle()] = item.getResponse();
47
    }
48
    
49
    let created = Utilities.parseDate(obj[Created], "GMT", "yyyy-MM-dd HH:mm:ss.sss").getTime();
50
    let updated = obj[Updated] ? Utilities.parseDate(obj[Updated], "GMT", "yyyy-MM-dd HH:mm:ss.sss").getTime() : created;
51
    const Diff = 5 * 1000;
52
53
    if (updated - created <= Diff) {
54
        // No updated since the timespan is too low
55
        let endPoint = PropertiesService.getScriptProperties().getProperty("EndPoint");
56
        
57
        if (endPoint) {
58
            endPoint = endPoint.replace(`{${Id}}`, encodeURI(obj[Id]));
59
            endPoint = endPoint.replace(`{${EditUrl}}`, encodeURI(formResponse.getEditResponseUrl().replace("viewform?", "formResponse?")));
60
            UrlFetchApp.fetch(endPoint);
61
        }
62
    }
63
}
64
```
65 5 Lê Sĩ Quý
66 7 Lê Sĩ Quý
- Lấy New Url của form Document-Links (form phụ) theo cách ở trên, ví dụ: https://docs.google.com/forms/d/e/ **1FAIpQLScYAXtjFMy8N4vWz3t_ujZRJ-cRx5idKGUR8EQ-sFLYxc-qVQ** /formResponse?entry.329640571={Id}&entry.463446545={EditUrl}
67
68 8 Lê Sĩ Quý
*Nếu bạn copy từ template thì field id của Id và EditUrl sẽ không đổi, việc của bạn là thay thế FormId (bôi đậm) băng FormId của file Document-Links sinh ra* 
69 7 Lê Sĩ Quý
70
- Thêm thuộc tính EndPoint cho Project với giá trị là Url vừa lấy được
71
72
![Thêm thuộc tính EndPoint](documents-endpoint-property.png) 
73
74 5 Lê Sĩ Quý
- Cài đặt trigger cho Form Documents như hình bên dưới
75
![Cài đặt trigger cho Database-Documents form](documents-trigger-setup.png)
76 9 Lê Sĩ Quý
77
### Xóa/Delete
78
79
Giải pháp của AKA Lab là sử dụng **soft delete** bằng cách cập nhật giá trị *IsDeleted= 1* nên việc DeleteUrl cơ bản giống EditUrl nhưng ngắn hơn do chỉ cập nhật giá trị column IsDeleted