1. Khái quát chung
Trong lớp học lập trình này, bạn sẽ tìm hiểu một số kiến thức cơ bản về Firebase để tạo các ứng dụng web tương tác. Bạn sẽ xây dựng ứng dụng trò chuyện trong sổ lưu bút và trả lời sự kiện bằng cách sử dụng một số sản phẩm của Firebase.
Bạn sẽ học được gì
- Xác thực người dùng bằng Xác thực Firebase và FirebaseUI.
- Đồng bộ hóa dữ liệu bằng Cloud Firestore.
- Viết Quy tắc bảo mật Firebase để bảo mật cơ sở dữ liệu.
Những gì bạn cần
- Trình duyệt bạn chọn, chẳng hạn như Chrome.
- Truy cập vào stackblitz.com (không cần tài khoản hoặc đăng nhập).
- Tài khoản Google, giống như tài khoản gmail. Chúng tôi khuyên dùng tài khoản email mà bạn đã sử dụng cho tài khoản GitHub của mình. Điều này cho phép bạn sử dụng các tính năng nâng cao trong StackBlitz.
- Mã mẫu của lớp học lập trình. Xem bước tiếp theo để biết cách lấy mã.
2. Lấy mã khởi đầu
Trong lớp học lập trình này, bạn xây dựng một ứng dụng bằng StackBlitz , một trình chỉnh sửa trực tuyến được tích hợp một số quy trình làm việc của Firebase. Stackblitz không yêu cầu cài đặt phần mềm hoặc tài khoản StackBlitz đặc biệt.
StackBlitz cho phép bạn chia sẻ dự án với người khác. Những người khác có URL dự án StackBlitz của bạn có thể xem mã và phân nhánh dự án của bạn, nhưng họ không thể chỉnh sửa dự án StackBlitz của bạn.
- Truy cập URL này để lấy mã bắt đầu: https://stackblitz.com/edit/firebase-gtk-web-start
- Ở đầu trang StackBlitz, nhấp vào Fork :
Bây giờ bạn có một bản sao mã bắt đầu làm dự án StackBlitz của riêng bạn, có một tên duy nhất cùng với một URL duy nhất. Tất cả các tệp và thay đổi của bạn đều được lưu trong dự án StackBlitz này.
3. Chỉnh sửa thông tin sự kiện
Tài liệu ban đầu cho lớp học lập trình này cung cấp một số cấu trúc cho ứng dụng web, bao gồm một số biểu định kiểu và một vài vùng chứa HTML cho ứng dụng. Ở phần sau của lớp học lập trình này, bạn sẽ kết nối các vùng chứa này với Firebase.
Để bắt đầu, chúng ta hãy làm quen hơn một chút với giao diện StackBlitz.
- Trong StackBlitz, mở tệp
index.html
. - Xác định vị trí
event-details-container
vàdescription-container
, sau đó thử chỉnh sửa một số chi tiết sự kiện.
Khi bạn chỉnh sửa văn bản, tính năng tải lại trang tự động trong StackBlitz sẽ hiển thị chi tiết sự kiện mới. Tuyệt vời phải không?
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
Bản xem trước ứng dụng của bạn sẽ trông giống như thế này:
Xem trước ứng dụng
4. Tạo và thiết lập dự án Firebase
Hiển thị thông tin sự kiện là điều tuyệt vời cho khách của bạn, nhưng chỉ hiển thị các sự kiện thì không hữu ích cho bất kỳ ai. Hãy thêm một số chức năng động vào ứng dụng này. Để làm được điều này, bạn sẽ cần kết nối Firebase với ứng dụng của mình. Để bắt đầu với Firebase, bạn cần tạo và thiết lập dự án Firebase.
Tạo dự án Firebase
- Đăng nhập vào Firebase .
- Trong bảng điều khiển Firebase, nhấp vào Thêm dự án (hoặc Tạo dự án ), sau đó đặt tên cho dự án Firebase của bạn là Firebase-Web-Codelab .
- Nhấp qua các tùy chọn tạo dự án. Chấp nhận các điều khoản của Firebase nếu được nhắc. Trên màn hình Google Analytics, hãy nhấp vào "Không bật" vì bạn sẽ không sử dụng Analytics cho ứng dụng này.
Để tìm hiểu thêm về các dự án Firebase, hãy xem Tìm hiểu các dự án Firebase .
Kích hoạt và thiết lập các sản phẩm Firebase trong bảng điều khiển
Ứng dụng bạn đang xây dựng sử dụng một số sản phẩm Firebase có sẵn cho ứng dụng web:
- Xác thực Firebase và Giao diện người dùng Firebase để dễ dàng cho phép người dùng đăng nhập vào ứng dụng của bạn.
- Cloud Firestore để lưu dữ liệu có cấu trúc trên đám mây và nhận thông báo ngay lập tức khi dữ liệu thay đổi.
- Quy tắc bảo mật Firebase để bảo mật cơ sở dữ liệu của bạn.
Một số sản phẩm này cần có cấu hình đặc biệt hoặc cần được bật bằng bảng điều khiển Firebase.
Cho phép đăng nhập email để xác thực Firebase
Để cho phép người dùng đăng nhập vào ứng dụng web, bạn sẽ sử dụng phương thức đăng nhập Email/Mật khẩu cho lớp học lập trình này:
- Trong bảng điều khiển bên trái của bảng điều khiển Firebase, nhấp vào Build > Authentication . Sau đó nhấp vào Bắt đầu . Bây giờ bạn đang ở trong Trang tổng quan xác thực, nơi bạn có thể xem người dùng đã đăng ký, định cấu hình nhà cung cấp dịch vụ đăng nhập và quản lý cài đặt.
- Chọn tab Phương thức đăng nhập (hoặc nhấp vào đây để đi thẳng đến tab).
- Nhấp vào Email/Mật khẩu từ tùy chọn nhà cung cấp, chuyển nút gạt sang Bật , sau đó nhấp vào Lưu .
Thiết lập Cloud Firestore
Ứng dụng web sử dụng Cloud Firestore để lưu tin nhắn trò chuyện và nhận tin nhắn trò chuyện mới.
Dưới đây là cách thiết lập Cloud Firestore:
- Trong bảng điều khiển bên trái của bảng điều khiển Firebase, nhấp vào Build > Firestore Database . Sau đó nhấn Tạo cơ sở dữ liệu .
- Nhấp vào Tạo cơ sở dữ liệu .
- Chọn tùy chọn Bắt đầu ở chế độ thử nghiệm . Đọc tuyên bố từ chối trách nhiệm về các quy tắc bảo mật. Chế độ kiểm tra đảm bảo rằng bạn có thể tự do ghi vào cơ sở dữ liệu trong quá trình phát triển. Bấm tiếp .
- Chọn vị trí cho cơ sở dữ liệu của bạn (bạn chỉ có thể sử dụng mặc định). Tuy nhiên, xin lưu ý rằng sau này bạn không thể thay đổi vị trí này.
- Nhấp vào Xong .
5. Thêm và định cấu hình Firebase
Bây giờ bạn đã tạo dự án Firebase và bật một số dịch vụ, bạn cần cho biết mã mà bạn muốn sử dụng Firebase cũng như dự án Firebase nào sẽ sử dụng.
Thêm thư viện Firebase
Để ứng dụng của bạn sử dụng Firebase, bạn cần thêm thư viện Firebase vào ứng dụng. Có nhiều cách để thực hiện việc này, như được mô tả trong tài liệu về Firebase . Ví dụ: bạn có thể thêm thư viện từ CDN của Google hoặc bạn có thể cài đặt chúng cục bộ bằng npm rồi đóng gói chúng trong ứng dụng của mình nếu bạn đang sử dụng Browserify.
StackBlitz cung cấp tính năng đóng gói tự động nên bạn có thể thêm thư viện Firebase bằng cách sử dụng câu lệnh nhập. Bạn sẽ sử dụng các phiên bản mô-đun (v9) của thư viện, giúp giảm kích thước tổng thể của trang web thông qua quá trình được gọi là "rung cây". Bạn có thể tìm hiểu thêm về SDK mô-đun trong tài liệu .
Để xây dựng ứng dụng này, bạn sử dụng thư viện Xác thực Firebase, FirebaseUI và Cloud Firestore. Đối với lớp học lập trình này, các câu lệnh nhập sau đã được đưa vào đầu tệp index.js
và chúng tôi sẽ nhập thêm các phương thức từ mỗi thư viện Firebase trong tương lai:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
Thêm ứng dụng web Firebase vào dự án Firebase của bạn
- Quay lại bảng điều khiển Firebase, điều hướng đến trang tổng quan về dự án của bạn bằng cách nhấp vào Tổng quan về dự án ở trên cùng bên trái.
- Ở giữa trang tổng quan về dự án của bạn, hãy nhấp vào biểu tượng web để tạo một ứng dụng web Firebase mới.
- Đăng ký ứng dụng với biệt danh Web App .
- Đối với lớp học lập trình này, KHÔNG chọn hộp bên cạnh Đồng thời thiết lập dịch vụ lưu trữ Firebase cho ứng dụng này . Bây giờ bạn sẽ sử dụng khung xem trước của StackBlitz.
- Nhấn vào Đăng ký ứng dụng .
- Sao chép đối tượng cấu hình Firebase vào khay nhớ tạm của bạn.
- Nhấp vào Tiếp tục với bảng điều khiển .Thêm đối tượng cấu hình Firebase vào ứng dụng của bạn:
- Quay lại StackBlitz, đi tới tệp
index.js
. - Xác định vị trí dòng nhận xét
Add Firebase project configuration object here
, sau đó dán đoạn mã cấu hình của bạn ngay bên dưới nhận xét. - Thêm lệnh gọi hàm
initializeApp
để thiết lập Firebase bằng cấu hình dự án Firebase duy nhất của bạn.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.appspot.com", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. Thêm thông tin đăng nhập của người dùng (RSVP)
Bây giờ bạn đã thêm Firebase vào ứng dụng, bạn có thể thiết lập nút RSVP để đăng ký mọi người bằng Xác thực Firebase .
Xác thực người dùng của bạn bằng Đăng nhập email và FirebaseUI
Bạn sẽ cần nút Trả lời nhắc người dùng đăng nhập bằng địa chỉ email của họ. Bạn có thể thực hiện việc này bằng cách kết nối FirebaseUI với nút RSVP. FirebaseUI là thư viện cung cấp cho bạn giao diện người dùng dựng sẵn trên Firebase Auth.
FirebaseUI yêu cầu cấu hình (xem các tùy chọn trong tài liệu ) để thực hiện hai việc:
- Cho FirebaseUI biết rằng bạn muốn sử dụng phương thức đăng nhập Email/Mật khẩu .
- Xử lý lệnh gọi lại để đăng nhập thành công và trả về false để tránh chuyển hướng. Bạn không muốn trang được làm mới vì bạn đang xây dựng một ứng dụng web một trang.
Thêm mã để khởi tạo FirebaseUI Auth
- Trong StackBlitz, đi tới tệp
index.js
. - Ở trên cùng, tìm câu lệnh nhập
firebase/auth
, sau đó thêmgetAuth
vàEmailAuthProvider
, như sau:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- Lưu tham chiếu đến đối tượng xác thực ngay sau
initializeApp
, như sau:initializeApp(firebaseConfig); auth = getAuth();
- Lưu ý rằng cấu hình FirebaseUI đã được cung cấp trong mã bắt đầu. Nó đã được thiết lập để sử dụng nhà cung cấp xác thực email.
- Ở cuối hàm
main()
trongindex.js
, hãy thêm câu lệnh khởi tạo FirebaseUI, như sau:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
Thêm nút RSVP vào HTML
- Trong StackBlitz, đi tới tệp
index.html
. - Thêm HTML cho nút RSVP bên trong
event-details-container
như trong ví dụ bên dưới.
Hãy cẩn thận khi sử dụng các giá trịid
giống như hiển thị bên dưới vì đối với lớp học lập trình này, đã có sẵn các hook cho các ID cụ thể này trong tệpindex.js
.
Lưu ý rằng trong tệpindex.html
, có một vùng chứa có IDfirebaseui-auth-container
. Đây là ID mà bạn sẽ chuyển tới FirebaseUI để giữ thông tin đăng nhập của bạn.
Xem trước ứng dụng<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- Thiết lập trình nghe trên nút RSVP và gọi hàm khởi động FirebaseUI. Điều này cho FirebaseUI biết rằng bạn muốn xem cửa sổ đăng nhập.
Thêm đoạn mã sau vào cuối hàmmain()
trongindex.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
Kiểm tra đăng nhập vào ứng dụng
- Trong cửa sổ xem trước của StackBlitz, nhấp vào nút RSVP để đăng nhập vào ứng dụng.
- Đối với lớp học lập trình này, bạn có thể sử dụng bất kỳ địa chỉ email nào, thậm chí là địa chỉ email giả vì bạn chưa thiết lập bước xác minh email cho lớp học lập trình này.
- Nếu bạn thấy thông báo lỗi cho biết
auth/operation-not-allowed
hoặcThe given sign-in provider is disabled for this Firebase project
, hãy kiểm tra để đảm bảo rằng bạn đã bật Email/Mật khẩu làm nhà cung cấp đăng nhập trong bảng điều khiển Firebase.
- Chuyển đến trang tổng quan Xác thực trong bảng điều khiển Firebase. Trong tab Người dùng , bạn sẽ thấy thông tin tài khoản bạn đã nhập để đăng nhập vào ứng dụng.
Thêm trạng thái xác thực vào giao diện người dùng
Tiếp theo, hãy đảm bảo rằng giao diện người dùng phản ánh thực tế là bạn đã đăng nhập.
Bạn sẽ sử dụng lệnh gọi lại trình nghe trạng thái Xác thực Firebase, lệnh này sẽ được thông báo bất cứ khi nào trạng thái đăng nhập của người dùng thay đổi. Nếu hiện có người dùng đã đăng nhập, ứng dụng của bạn sẽ chuyển nút "RSVP" thành nút "đăng xuất".
- Trong StackBlitz, đi tới tệp
index.js
. - Ở trên cùng, tìm câu lệnh nhập
firebase/auth
, sau đó thêmsignOut
vàonAuthStateChanged
, như sau:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore';
- Thêm đoạn mã sau vào cuối hàm
main()
:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main();
- Trong trình nghe nút, kiểm tra xem có người dùng hiện tại hay không và đăng xuất họ. Để thực hiện việc này, hãy thay thế
startRsvpButton.addEventListener
hiện tại bằng:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
Bây giờ, nút trong ứng dụng của bạn sẽ hiển thị LOGOUT và nút này sẽ chuyển trở lại RSVP khi được nhấp vào.
Xem trước ứng dụng
7. Viết tin nhắn lên Cloud Firestore
Biết rằng người dùng sẽ đến là điều tuyệt vời nhưng chúng ta hãy giao cho khách những việc khác để làm trong ứng dụng. Điều gì sẽ xảy ra nếu họ có thể để lại tin nhắn trong sổ lưu bút? Họ có thể chia sẻ lý do tại sao họ lại hào hứng đến đây hoặc họ muốn gặp ai.
Để lưu trữ tin nhắn trò chuyện mà người dùng viết trong ứng dụng, bạn sẽ sử dụng Cloud Firestore .
Mô hình dữ liệu
Cloud Firestore là cơ sở dữ liệu NoSQL và dữ liệu được lưu trữ trong cơ sở dữ liệu được chia thành các bộ sưu tập, tài liệu, trường và bộ sưu tập con. Bạn sẽ lưu trữ từng tin nhắn trò chuyện dưới dạng tài liệu trong bộ sưu tập cấp cao nhất có tên là guestbook
.
Thêm tin nhắn vào Firestore
Trong phần này, bạn sẽ thêm chức năng để người dùng viết tin nhắn mới vào cơ sở dữ liệu. Trước tiên, bạn thêm HTML cho các thành phần giao diện người dùng (trường thông báo và nút gửi). Sau đó, bạn thêm mã nối các phần tử này vào cơ sở dữ liệu.
Để thêm các thành phần UI của trường tin nhắn và nút gửi:
- Trong StackBlitz, đi tới tệp
index.html
. - Xác định vị trí
guestbook-container
, sau đó thêm HTML sau để tạo biểu mẫu có trường nhập tin nhắn và nút gửi.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
Xem trước ứng dụng
Người dùng nhấp vào nút GỬI sẽ kích hoạt đoạn mã bên dưới. Nó thêm nội dung của trường nhập tin nhắn vào bộ sưu tập guestbook
của cơ sở dữ liệu. Cụ thể, phương thức addDoc
thêm nội dung tin nhắn vào tài liệu mới (có ID được tạo tự động) vào bộ sưu tập guestbook
.
- Trong StackBlitz, đi tới tệp
index.js
. - Ở trên cùng, tìm câu lệnh nhập
firebase/firestore
, sau đó thêmgetFirestore
,addDoc
vàcollection
, như vậy:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore';
- Bây giờ chúng ta sẽ lưu một tham chiếu đến đối tượng
db
Firestore ngay sauinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- Ở cuối hàm
main()
, thêm đoạn mã sau.
Lưu ý rằngauth.currentUser.uid
là tham chiếu đến ID duy nhất được tạo tự động mà Xác thực Firebase cung cấp cho tất cả người dùng đã đăng nhập.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
Chỉ hiển thị sổ lưu bút cho người dùng đã đăng nhập
Bạn không muốn bất cứ ai nhìn thấy cuộc trò chuyện của khách. Một điều bạn có thể làm để bảo mật cuộc trò chuyện là chỉ cho phép người dùng đã đăng nhập xem sổ lưu bút. Điều đó có nghĩa là, đối với các ứng dụng của riêng bạn, bạn cũng sẽ muốn bảo mật cơ sở dữ liệu của mình bằng Quy tắc bảo mật Firebase . (Sau này sẽ có thêm thông tin về các quy tắc bảo mật trong lớp học lập trình.)
- Trong StackBlitz, đi tới tệp
index.js
. - Chỉnh sửa trình nghe
onAuthStateChanged
để ẩn và hiển thị sổ lưu bút.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
Kiểm tra việc gửi tin nhắn
- Đảm bảo rằng bạn đã đăng nhập vào ứng dụng.
- Nhập tin nhắn chẳng hạn như "Xin chào!", sau đó nhấp vào GỬI .
Hành động này ghi thông báo vào cơ sở dữ liệu Cloud Firestore của bạn. Tuy nhiên, bạn sẽ chưa thấy thông báo trong ứng dụng web thực tế của mình vì bạn vẫn cần triển khai truy xuất dữ liệu. Bạn sẽ làm điều đó tiếp theo.
Nhưng bạn có thể thấy thông báo mới được thêm vào trong bảng điều khiển Firebase.
Trong bảng điều khiển Firebase, trong bảng điều khiển Cơ sở dữ liệu Firestore , bạn sẽ thấy bộ sưu tập guestbook
cùng với thông báo mới được thêm của mình. Nếu bạn tiếp tục gửi tin nhắn, bộ sưu tập sổ lưu bút của bạn sẽ chứa nhiều tài liệu, như sau:
Bảng điều khiển Firebase
8. Đọc tin nhắn
Đồng bộ hóa tin nhắn
Thật thú vị khi khách có thể viết tin nhắn vào cơ sở dữ liệu nhưng họ chưa thể nhìn thấy chúng trong ứng dụng.
Để hiển thị thông báo, bạn cần thêm trình nghe kích hoạt khi dữ liệu thay đổi, sau đó tạo thành phần giao diện người dùng hiển thị thông báo mới.
Bạn sẽ thêm mã để nghe tin nhắn mới được thêm từ ứng dụng. Đầu tiên, thêm một phần trong HTML để hiển thị thông báo:
- Trong StackBlitz, đi tới tệp
index.html
. - Trong
guestbook-container
, thêm một phần mới với ID củaguestbook
.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
Tiếp theo, đăng ký trình nghe để lắng nghe những thay đổi được thực hiện đối với dữ liệu:
- Trong StackBlitz, đi tới tệp
index.js
. - Ở trên cùng, tìm câu lệnh nhập
firebase/firestore
, sau đó thêmquery
,orderBy
vàonSnapshot
, như sau:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- Ở cuối hàm
main()
, thêm đoạn mã sau để lặp qua tất cả các tài liệu (tin nhắn sổ lưu bút) trong cơ sở dữ liệu. Để tìm hiểu thêm về những gì đang xảy ra trong mã này, hãy đọc thông tin bên dưới đoạn mã.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
Để nghe tin nhắn trong cơ sở dữ liệu, bạn đã tạo một truy vấn trên một bộ sưu tập cụ thể bằng cách sử dụng chức năng bộ collection
. Đoạn mã trên lắng nghe những thay đổi trong bộ sưu tập guestbook
, đây là nơi lưu trữ các tin nhắn trò chuyện. Các tin nhắn cũng được sắp xếp theo ngày, sử dụng orderBy('timestamp', 'desc')
để hiển thị các tin nhắn mới nhất ở trên cùng.
Hàm onSnapshot
có hai tham số: truy vấn sẽ sử dụng và hàm gọi lại. Chức năng gọi lại được kích hoạt khi có bất kỳ thay đổi nào đối với tài liệu khớp với truy vấn. Điều này có thể xảy ra nếu tin nhắn bị xóa, sửa đổi hoặc thêm vào. Để biết thêm thông tin, hãy xem tài liệu Cloud Firestore .
Kiểm tra việc đồng bộ hóa tin nhắn
Cloud Firestore tự động đồng bộ hóa dữ liệu ngay lập tức với các máy khách đã đăng ký cơ sở dữ liệu.
- Các tin nhắn bạn đã tạo trước đó trong cơ sở dữ liệu sẽ được hiển thị trong ứng dụng. Hãy thoải mái viết tin nhắn mới; chúng sẽ xuất hiện ngay lập tức.
- Nếu bạn mở không gian làm việc của mình trong nhiều cửa sổ hoặc tab, tin nhắn sẽ đồng bộ hóa theo thời gian thực trên các tab.
- (Tùy chọn) Bạn có thể thử xóa, sửa đổi hoặc thêm tin nhắn mới theo cách thủ công trực tiếp trong phần Cơ sở dữ liệu của bảng điều khiển Firebase; mọi thay đổi sẽ xuất hiện trong giao diện người dùng.
Chúc mừng! Bạn đang đọc tài liệu Cloud Firestore trong ứng dụng của mình!
Xem trước ứng dụng
9. Thiết lập các quy tắc bảo mật cơ bản
Ban đầu, bạn thiết lập Cloud Firestore để sử dụng chế độ thử nghiệm, nghĩa là cơ sở dữ liệu của bạn mở để đọc và ghi. Tuy nhiên, bạn chỉ nên sử dụng chế độ thử nghiệm trong giai đoạn phát triển đầu tiên. Cách tốt nhất là bạn nên thiết lập các quy tắc bảo mật cho cơ sở dữ liệu khi phát triển ứng dụng của mình. Bảo mật phải là một phần không thể thiếu đối với cấu trúc và hành vi của ứng dụng của bạn.
Quy tắc bảo mật cho phép bạn kiểm soát quyền truy cập vào tài liệu và bộ sưu tập trong cơ sở dữ liệu của mình. Cú pháp quy tắc linh hoạt cho phép bạn tạo các quy tắc khớp với mọi thứ từ tất cả các thao tác ghi vào toàn bộ cơ sở dữ liệu đến các thao tác trên một tài liệu cụ thể.
Bạn có thể viết các quy tắc bảo mật cho Cloud Firestore trong bảng điều khiển Firebase:
- Trong phần Build của bảng điều khiển Firebase, nhấp vào Cơ sở dữ liệu Firestore , sau đó chọn tab Quy tắc (hoặc nhấp vào đây để chuyển thẳng đến tab Quy tắc ).
- Bạn sẽ thấy các quy tắc bảo mật mặc định sau đây, với giới hạn thời gian truy cập công khai sau vài tuần kể từ hôm nay.
Xác định bộ sưu tập
Đầu tiên, xác định các bộ sưu tập mà ứng dụng ghi dữ liệu vào đó.
- Xóa
match /{document=**}
đối sánh hiện có để các quy tắc của bạn trông như thế này:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- Trong
match /databases/{database}/documents
, xác định bộ sưu tập mà bạn muốn bảo mật:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
Thêm quy tắc bảo mật
Vì bạn đã sử dụng UID xác thực làm trường trong mỗi tài liệu sổ lưu bút nên bạn có thể lấy UID xác thực và xác minh rằng bất kỳ ai cố gắng ghi vào tài liệu đều có UID xác thực phù hợp.
- Thêm quy tắc đọc và ghi vào bộ quy tắc của bạn như hiển thị bên dưới:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } }
- Nhấp vào Xuất bản để triển khai các quy tắc mới của bạn. Bây giờ, đối với sổ lưu bút, chỉ người dùng đã đăng nhập mới có thể đọc tin nhắn (bất kỳ tin nhắn nào!), nhưng bạn chỉ có thể tạo tin nhắn bằng ID người dùng của mình. Chúng tôi cũng không cho phép chỉnh sửa hoặc xóa tin nhắn.
Thêm quy tắc xác thực
- Thêm xác thực dữ liệu để đảm bảo rằng tất cả các trường dự kiến đều có trong tài liệu:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } }
- Nhấp vào Xuất bản để triển khai các quy tắc mới của bạn.
Đặt lại người nghe
Vì ứng dụng của bạn hiện chỉ cho phép người dùng được xác thực đăng nhập nên bạn nên di chuyển truy vấn firestore
của sổ lưu bút bên trong trình nghe Xác thực. Nếu không, lỗi quyền sẽ xảy ra và ứng dụng sẽ bị ngắt kết nối khi người dùng đăng xuất.
- Trong StackBlitz, đi tới tệp
index.js
. - Kéo bộ sưu tập sổ lưu bút trên trình
onSnapshot
vào một hàm mới có tên làsubscribeGuestbook
. Ngoài ra, hãy gán kết quả của hàmonSnapshot
cho biếnguestbookListener
.
Trình nghe FirestoreonSnapshot
trả về chức năng hủy đăng ký mà bạn có thể sử dụng để hủy trình nghe ảnh chụp nhanh sau này.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); }
- Thêm một chức năng mới bên dưới được gọi là
unsubscribeGuestbook
. Kiểm tra xem biếnguestbookListener
có phải là null hay không, sau đó gọi hàm để hủy trình nghe.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
Cuối cùng, thêm các hàm mới vào lệnh gọi lại onAuthStateChanged
.
- Thêm
subscribeGuestbook()
vào cuốiif (user)
. - Thêm
unsubscribeGuestbook()
vào cuối câu lệnhelse
.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. Bước bổ sung: Thực hành những gì bạn đã học
Ghi lại trạng thái trả lời của người tham dự
Hiện tại, ứng dụng của bạn chỉ cho phép mọi người bắt đầu trò chuyện nếu họ quan tâm đến sự kiện này. Ngoài ra, cách duy nhất để bạn biết ai đó có đến hay không là họ đăng nội dung đó trong cuộc trò chuyện. Hãy tổ chức và cho mọi người biết có bao nhiêu người sẽ đến.
Bạn sẽ thêm nút chuyển đổi để đăng ký những người muốn tham dự sự kiện, sau đó thu thập số lượng người sẽ đến.
- Trong StackBlitz, đi tới tệp
index.html
. - Trong
guestbook-container
, thêm một bộ nút CÓ và KHÔNG , như sau:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
Xem trước ứng dụng
Tiếp theo, đăng ký trình nghe cho các lần nhấp vào nút. Nếu người dùng nhấp vào CÓ thì hãy sử dụng UID xác thực của họ để lưu phản hồi vào cơ sở dữ liệu.
- Trong StackBlitz, đi tới tệp
index.js
. - Ở trên cùng, tìm câu lệnh nhập
firebase/firestore
, sau đó thêmdoc
,setDoc
vàwhere
, như sau:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore';
- Ở cuối hàm
main()
, thêm đoạn mã sau để nghe trạng thái RSVP:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main();
- Tiếp theo, tạo một bộ sưu tập mới có tên là
attendees
, sau đó đăng ký tham chiếu tài liệu nếu nhấp vào nút RSVP. Đặt tham chiếu đó thànhtrue
hoặcfalse
tùy thuộc vào nút nào được nhấp vào.
Đầu tiên, đối vớirsvpYes
:
Sau đó, tương tự với// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };
rsvpNo
, nhưng với giá trịfalse
:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
Cập nhật Quy tắc bảo mật của bạn
Vì bạn đã thiết lập một số quy tắc nên dữ liệu mới mà bạn thêm bằng các nút sẽ bị từ chối.
Cho phép bổ sung vào bộ sưu tập attendees
Bạn sẽ cần cập nhật các quy tắc để cho phép thêm vào bộ sưu tập attendees
.
- Đối với bộ sưu tập
attendees
, vì bạn đã sử dụng UID xác thực làm tên tài liệu nên bạn có thể lấy nó và xác minh rằnguid
của người gửi giống với tài liệu họ đang viết. Bạn sẽ cho phép mọi người đọc danh sách người tham dự (vì không có dữ liệu riêng tư ở đó), nhưng chỉ người tạo mới có thể cập nhật danh sách đó.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } }
- Nhấp vào Xuất bản để triển khai các quy tắc mới của bạn.
Thêm quy tắc xác thực
- Thêm một số quy tắc xác thực dữ liệu để đảm bảo rằng tất cả các trường dự kiến đều có trong tài liệu:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } }
- Đừng quên nhấp vào Xuất bản để triển khai các quy tắc của bạn!
(Tùy chọn) Bây giờ bạn có thể xem kết quả của việc nhấp vào nút. Chuyển đến bảng điều khiển Cloud Firestore của bạn trong bảng điều khiển Firebase.
Đọc trạng thái trả lời
Bây giờ bạn đã ghi lại các câu trả lời, hãy xem ai sẽ đến và phản ánh điều đó trong giao diện người dùng.
- Trong StackBlitz, đi tới tệp
index.html
. - Trong
description-container
, thêm phần tử mới có IDnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
Tiếp theo, đăng ký trình nghe cho bộ sưu tập attendees
và đếm số lượng phản hồi CÓ :
- Trong StackBlitz, đi tới tệp
index.js
. - Ở cuối hàm
main()
, hãy thêm đoạn mã sau để nghe trạng thái RSVP và đếm số lần nhấp CÓ .async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
Cuối cùng, hãy đánh dấu nút tương ứng với trạng thái hiện tại.
- Tạo một hàm kiểm tra xem UID xác thực hiện tại có mục nhập trong bộ sưu tập
attendees
hay không, sau đó đặt lớp nút thành đãclicked
.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); }
- Ngoài ra, hãy tạo một chức năng để hủy đăng ký. Điều này sẽ được sử dụng khi người dùng đăng xuất.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; }
- Gọi các hàm từ trình nghe Xác thực.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subscribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } });
- Hãy thử đăng nhập với tư cách nhiều người dùng và xem số lượng tăng lên sau mỗi lần nhấp vào nút CÓ bổ sung.
Xem trước ứng dụng
11. Xin chúc mừng!
Bạn đã sử dụng Firebase để xây dựng một ứng dụng web tương tác theo thời gian thực!
Những gì chúng tôi đã đề cập
- Xác thực Firebase
- FirebaseUI
- Cửa hàng đám mây
- Quy tắc bảo mật của Firebase
Bước tiếp theo
- Bạn muốn tìm hiểu thêm Quy trình làm việc của nhà phát triển Firebase? Hãy xem lớp học lập trình về trình mô phỏng Firebase để tìm hiểu cách thử nghiệm và chạy ứng dụng của bạn hoàn toàn cục bộ.
- Bạn muốn tìm hiểu thêm về các sản phẩm Firebase khác? Có thể bạn muốn lưu trữ file hình ảnh mà người dùng tải lên? Hoặc gửi thông báo cho người dùng của bạn? Hãy xem lớp học lập trình web Firebase để biết lớp học lập trình chuyên sâu hơn về nhiều sản phẩm Firebase dành cho web khác.
- Bạn muốn tìm hiểu thêm về Cloud Firestore? Có lẽ bạn muốn tìm hiểu về các bộ sưu tập con và giao dịch? Hãy truy cập lớp học lập trình web Cloud Firestore để có lớp học lập trình chuyên sâu hơn về Cloud Firestore. Hoặc xem loạt video YouTube này để tìm hiểu về Cloud Firestore !
Tìm hiểu thêm
- Trang web Firebase: firebase.google.com
- Kênh YouTube của Firebase
Nó diễn ra như thế nào?
Chúng tôi rất thích những phản hồi của bạn! Vui lòng điền vào một mẫu đơn ngắn (rất) ở đây .