Lớp học lập trình web AngularFire

1. Khái quát chung

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách sử dụng AngularFire để tạo các ứng dụng web bằng cách triển khai và triển khai ứng dụng trò chuyện bằng các sản phẩm và dịch vụ của Firebase.

angularfire-2.png

Bạn sẽ học được gì

  • Xây dựng ứng dụng web bằng Angular và Firebase.
  • Đồng bộ hóa dữ liệu bằng Cloud Firestore và Cloud Storage cho Firebase.
  • Xác thực người dùng của bạn bằng Xác thực Firebase.
  • Triển khai ứng dụng web của bạn trên Firebase Hosting.
  • Gửi thông báo bằng Nhắn tin qua đám mây của Firebase.
  • Thu thập dữ liệu hiệu suất của ứng dụng web của bạn.

Những gì bạn cần

  • Trình soạn thảo IDE/văn bản bạn chọn, chẳng hạn như WebStorm , Atom , Sublime hoặc VS Code
  • Trình quản lý gói npm , thường đi kèm với Node.js
  • Một thiết bị đầu cuối/bảng điều khiển
  • Trình duyệt bạn chọn, chẳng hạn như Chrome
  • Mã mẫu của lớp học lập trình (Xem bước tiếp theo của lớp học lập trình để biết cách lấy mã.)

2. Lấy mã mẫu

Sao chép kho lưu trữ GitHub của lớp học lập trình từ dòng lệnh:

git clone https://github.com/firebase/codelab-friendlychat-web

Ngoài ra, nếu bạn chưa cài đặt git, bạn có thể tải xuống kho lưu trữ dưới dạng tệp ZIP .

Nhập ứng dụng khởi đầu

Sử dụng IDE của bạn, mở hoặc nhập thư mục 📁 angularfire-start từ kho lưu trữ nhân bản. Thư mục 📁 angularfire-start này chứa mã khởi đầu cho lớp học lập trình, đây sẽ là một ứng dụng web trò chuyện có đầy đủ chức năng.

3. Tạo và thiết lập dự án Firebase

Tạo dự án Firebase

  1. Đăng nhập vào Firebase .
  2. Trong bảng điều khiển Firebase, hãy nhấp vào Thêm dự án rồi đặt tên cho dự án Firebase của bạn là FriendlyChat . Hãy nhớ ID dự án cho dự án Firebase của bạn.
  3. Bỏ chọn Bật Google Analytics cho dự án này
  4. Nhấp vào Tạo dự án .

Ứng dụng bạn sắp xây dựng sử dụng các sản phẩm Firebase có sẵn cho ứng dụng web:

  • Xác thực 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.
  • Cloud Storage cho Firebase để lưu tệp trên đám mây.
  • Firebase Hosting để lưu trữ và phục vụ nội dung của bạn.
  • Firebase Cloud Messaging để gửi thông báo đẩy và hiển thị thông báo bật lên của trình duyệt.
  • Giám sát hiệu suất Firebase để thu thập dữ liệu hiệu suất người dùng cho ứng dụng 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.

Thêm ứng dụng web Firebase vào dự án

  1. Nhấp vào biểu tượng trang web 58d6543a156e56f9.png để tạo một ứng dụng web Firebase mới.
  2. Đăng ký ứng dụng với biệt hiệu Trò chuyện thân thiện , sau đó chọn hộp bên cạnh Đồng thời thiết lập Firebase Hosting cho ứng dụng này . Nhấn vào Đăng ký ứng dụng .
  3. Ở bước tiếp theo, bạn sẽ thấy một đối tượng cấu hình. Chỉ sao chép đối tượng JS (không phải HTML xung quanh) vào firebase-config.js

Đăng ký ảnh chụp màn hình ứng dụng web

Cho phép đăng nhập Google để xác thực Firebase

Để cho phép người dùng đăng nhập vào ứng dụng web bằng tài khoản Google của họ, bạn sẽ sử dụng phương thức đăng nhập Google .

Bạn sẽ cần kích hoạt đăng nhập bằng Google :

  1. Trong bảng điều khiển Firebase, tìm phần Xây dựng ở bảng điều khiển bên trái.
  2. Nhấp vào Xác thực , sau đó nhấp vào tab Phương thức đăng nhập (hoặc nhấp vào đây để truy cập trực tiếp vào đó).
  3. Kích hoạt nhà cung cấp dịch vụ đăng nhập Google , sau đó nhấp vào Lưu .
  4. Đặt tên công khai cho ứng dụng của bạn thành Trò chuyện thân thiện và chọn email hỗ trợ Dự án từ menu thả xuống.
  5. Định cấu hình màn hình đồng ý OAuth của bạn trong Google Cloud Console và thêm biểu trưng:

d89fb3873b5d36ae.png

Kích hoạt 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.

Bạn sẽ cần kích hoạt Cloud Firestore:

  1. Trong phần Build của bảng điều khiển Firebase, nhấp vào Cơ sở dữ liệu Firestore .
  2. Nhấp vào Tạo cơ sở dữ liệu trong ngăn Cloud Firestore.

729991a081e7cd5.png

  1. Chọn tùy chọn Bắt đầu ở chế độ thử nghiệm , sau đó nhấp vào Tiếp theo sau khi đọ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ạn sẽ làm cho cơ sở dữ liệu của chúng tôi an toàn hơn sau này trong lớp học lập trình này.

77e4986cbeaf9dee.png

  1. Đặt vị trí lưu trữ dữ liệu Cloud Firestore của bạn. Bạn có thể để mặc định hoặc chọn khu vực gần bạn. Nhấp vào Xong để cung cấp Firestore.

9f2bb0d4e7ca49c7.png

Kích hoạt bộ nhớ đám mây

Ứng dụng web sử dụng Cloud Storage cho Firebase để lưu trữ, tải lên và chia sẻ hình ảnh.

Bạn sẽ cần bật Cloud Storage:

  1. Trong phần Build của bảng điều khiển Firebase, hãy nhấp vào Storage .
  2. Nếu không có nút Bắt đầu nghĩa là Bộ nhớ đám mây đã được bật và bạn không cần thực hiện các bước bên dưới.
  3. Nhấp vào Bắt đầu .
  4. Đọc tuyên bố từ chối trách nhiệm về các quy tắc bảo mật cho dự án Firebase của bạn, sau đó nhấp vào Tiếp theo .

Với các quy tắc bảo mật mặc định, bất kỳ người dùng được xác thực nào cũng có thể ghi bất cứ thứ gì vào Cloud Storage. Bạn sẽ làm cho bộ nhớ của chúng tôi an toàn hơn sau này trong lớp học lập trình này.

62f1afdcd1260127.png

  1. Vị trí Cloud Storage được chọn trước cùng khu vực bạn đã chọn cho cơ sở dữ liệu Cloud Firestore của mình. Nhấn Done để hoàn tất việc thiết lập.

1d7f49ebaddb32fc.png

4. Cài đặt giao diện dòng lệnh Firebase

Giao diện dòng lệnh Firebase (CLI) cho phép bạn sử dụng Firebase Hosting để phân phát ứng dụng web cục bộ cũng như triển khai ứng dụng web cho dự án Firebase của bạn.

  1. Cài đặt CLI bằng cách chạy lệnh npm sau:
npm -g install firebase-tools
  1. Xác minh rằng CLI đã được cài đặt chính xác bằng cách chạy lệnh sau:
firebase --version

Đảm bảo rằng phiên bản Firebase CLI là v4.1.0 trở lên.

  1. Cho phép Firebase CLI bằng cách chạy lệnh sau:
firebase login

Bạn đã thiết lập mẫu ứng dụng web để lấy cấu hình ứng dụng cho Firebase Hosting từ thư mục cục bộ của ứng dụng (kho lưu trữ mà bạn đã sao chép trước đó trong lớp học lập trình). Nhưng để kéo cấu hình, bạn cần liên kết ứng dụng của mình với dự án Firebase.

  1. Đảm bảo rằng dòng lệnh của bạn đang truy cập vào thư mục angularfire-start bộ của ứng dụng.
  2. Liên kết ứng dụng của bạn với dự án Firebase bằng cách chạy lệnh sau:
firebase use --add
  1. Khi được nhắc, hãy chọn ID dự án của bạn, sau đó đặt bí danh cho dự án Firebase của bạn.

Bí danh rất hữu ích nếu bạn có nhiều môi trường (sản xuất, dàn dựng, v.v.). Tuy nhiên, đối với lớp học lập trình này, chúng ta hãy chỉ sử dụng bí danh default .

  1. Thực hiện theo các hướng dẫn còn lại trên dòng lệnh của bạn.

5. Cài đặt AngularFire

Trước khi chạy dự án, hãy đảm bảo bạn đã thiết lập Angular CLI và AngularFire.

  1. Trong bảng điều khiển, chạy lệnh sau:
npm install -g @angular/cli
  1. Sau đó, trong bảng điều khiển từ thư mục angularfire-start , hãy chạy lệnh Angular CLI sau:
ng add @angular/fire

Điều này sẽ cài đặt tất cả các phụ thuộc cần thiết cho dự án của bạn.

  1. Khi được nhắc, hãy chọn các tính năng đã được thiết lập trong Bảng điều khiển Firebase ( ng deploy -- hosting , Authentication , Firestore , Cloud Functions (callable) , Cloud Messaging , Cloud Storage ) và làm theo lời nhắc trên bảng điều khiển.

6. Chạy ứng dụng khởi động cục bộ

Bây giờ bạn đã nhập và định cấu hình dự án của mình, bạn đã sẵn sàng chạy ứng dụng web lần đầu tiên.

  1. Trong bảng điều khiển từ thư mục angularfire-start , hãy chạy lệnh Firebase CLI sau:
firebase emulators:start
  1. Dòng lệnh của bạn sẽ hiển thị phản hồi sau:
✔  hosting: Local server: http://localhost:5000

Bạn đang sử dụng trình mô phỏng Firebase Hosting để phân phối ứng dụng của chúng tôi cục bộ. Ứng dụng web hiện có sẵn từ http://localhost:5000 . Tất cả các tệp nằm trong thư mục con src đều được phục vụ.

  1. Sử dụng trình duyệt của bạn, mở ứng dụng của bạn tại http://localhost:5000 .

Bạn sẽ thấy giao diện người dùng của ứng dụng FriendlyChat, giao diện này chưa (chưa!) hoạt động:

góc lửa-2.png

Ứng dụng không thể làm bất cứ điều gì ngay bây giờ, nhưng với sự giúp đỡ của bạn, nó sẽ sớm làm được! Cho đến nay, bạn chỉ trình bày giao diện người dùng cho mình.

Bây giờ chúng ta hãy xây dựng một cuộc trò chuyện theo thời gian thực!

7. Nhập và định cấu hình Firebase

Định cấu hình căn cứ hỏa lực

Bạn sẽ cần định cấu hình SDK Firebase để cho biết bạn đang sử dụng dự án Firebase nào.

  1. Chuyển đến cài đặt Dự án của bạn trong bảng điều khiển Firebase
  2. Trong thẻ "Ứng dụng của bạn", chọn biệt hiệu của ứng dụng mà bạn cần đối tượng cấu hình.
  3. Chọn "Cấu hình" từ ngăn đoạn mã Firebase SDK.

Bạn sẽ thấy rằng một tệp môi trường /angularfire-start/src/environments/environment.ts đã được tạo cho bạn.

  1. Sao chép đoạn mã đối tượng cấu hình, sau đó thêm nó vào angularfire-start/src/firebase-config.js .

environment.ts

export const environment = {
  firebase: {
    apiKey: "API_KEY",
    authDomain: "PROJECT_ID.firebaseapp.com",
    databaseURL: "https://PROJECT_ID.firebaseio.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.appspot.com",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
    measurementId: "G-MEASUREMENT_ID",
  },
};

Nhập khẩu AngularFire

Bạn sẽ thấy rằng các tính năng bạn đã chọn trong bảng điều khiển được tự động định tuyến trong tệp /angularfire-start/src/app/app.module.ts . Điều này cho phép ứng dụng của bạn sử dụng các tính năng và chức năng của Firebase. Tuy nhiên, để phát triển trong môi trường cục bộ, bạn cần kết nối chúng để sử dụng bộ Trình mô phỏng.

  1. Trong /angularfire-start/src/app/app.module.ts , tìm phần imports và sửa đổi các chức năng được cung cấp để kết nối với bộ Trình mô phỏng trong môi trường phi sản xuất.
// ...

import { provideAuth,getAuth, connectAuthEmulator } from '@angular/fire/auth';
import { provideFirestore,getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
import { provideFunctions,getFunctions, connectFunctionsEmulator } from '@angular/fire/functions';
import { provideMessaging,getMessaging } from '@angular/fire/messaging';
import { provideStorage,getStorage, connectStorageEmulator } from '@angular/fire/storage';

// ...

provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => {
    const auth = getAuth();
    if (location.hostname === 'localhost') {
        connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
    }
    return auth;
}),
provideFirestore(() => {
    const firestore = getFirestore();
    if (location.hostname === 'localhost') {
        connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
    }
    return firestore;
}),
provideFunctions(() => {
    const functions = getFunctions();
    if (location.hostname === 'localhost') {
        connectFunctionsEmulator(functions, '127.0.0.1', 5001);
    }
    return functions;
}),
provideStorage(() => {
    const storage = getStorage();
    if (location.hostname === 'localhost') {
        connectStorageEmulator(storage, '127.0.0.1', 5001);
    }
    return storage;
}),
provideMessaging(() => {
    return getMessaging();
}),

// ...

app.module.ts

Trong lớp học lập trình này, bạn sẽ sử dụng Xác thực Firebase, Cloud Firestore, Cloud Storage, Cloud Messaging và Giám sát hiệu suất, tức là bạn đang nhập tất cả thư viện của chúng. Trong các ứng dụng trong tương lai của bạn, hãy đảm bảo rằng bạn chỉ nhập những phần của Firebase mà bạn cần để rút ngắn thời gian tải ứng dụng.

8. Thiết lập đăng nhập người dùng

AngularFire bây giờ đã sẵn sàng để sử dụng vì nó đã được nhập và khởi tạo trong app.module.ts . Bây giờ bạn sẽ triển khai đăng nhập người dùng bằng Xác thực Firebase .

Xác thực người dùng của bạn bằng Đăng nhập bằng Google

Trong ứng dụng, khi người dùng nhấp vào nút Đăng nhập bằng Google , chức năng login sẽ được kích hoạt. (Bạn đã thiết lập điều đó cho mình!) Đối với lớp học lập trình này, bạn muốn ủy quyền cho Firebase sử dụng Google làm nhà cung cấp danh tính. Bạn sẽ sử dụng cửa sổ bật lên nhưng có một số phương pháp khác có sẵn từ Firebase.

  1. Trong thư mục angularfire-start , trong thư mục /src/app/services/ , hãy mở chat.service.ts .
  2. Tìm chức năng login .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Signs-in Friendly Chat.
login() {
    signInWithPopup(this.auth, this.provider).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        this.router.navigate(['/', 'chat']);
        return credential;
    })
}

Chức năng logout được kích hoạt khi người dùng nhấp vào nút Đăng xuất .

  1. Quay lại tệp src/app/services/chat.service.ts .
  2. Tìm chức năng logout .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Logout of Friendly Chat.
logout() {
    signOut(this.auth).then(() => {
        this.router.navigate(['/', 'login'])
        console.log('signed out');
    }).catch((error) => {
        console.log('sign out error: ' + error);
    })
}

Theo dõi trạng thái xác thực

Để cập nhật giao diện người dùng của chúng tôi cho phù hợp, bạn cần có cách kiểm tra xem người dùng đã đăng nhập hay đăng xuất. Với Xác thực Firebase, bạn có thể truy xuất trạng thái người dùng có thể quan sát được. Trạng thái này sẽ được kích hoạt mỗi khi trạng thái xác thực thay đổi.

  1. Quay lại tệp src/app/services/chat.service.ts .
  2. Tìm biến được gán user$ .
  3. Thay thế toàn bộ bài tập bằng đoạn mã sau.

chat.service.ts

// Observable user
user$ = user(this.auth);

Đoạn mã trên gọi hàm AngularFire user và trả về một người dùng có thể quan sát được. Nó sẽ kích hoạt mỗi khi trạng thái xác thực thay đổi (khi người dùng đăng nhập hoặc đăng xuất). Tại thời điểm này, bạn sẽ cập nhật giao diện người dùng để chuyển hướng, hiển thị người dùng trong điều hướng tiêu đề, v.v. Tất cả các phần giao diện người dùng này đã được triển khai.

Kiểm tra đăng nhập vào ứng dụng

  1. Nếu ứng dụng của bạn vẫn đang được phân phát, hãy làm mới ứng dụng của bạn trong trình duyệt. Nếu không, hãy chạy firebase emulators:start trên dòng lệnh để bắt đầu phân phát ứng dụng từ http://localhost:5000 , sau đó mở ứng dụng đó trong trình duyệt của bạn.
  2. Đăng nhập vào ứng dụng bằng nút đăng nhập và tài khoản Google của bạn. Nếu bạn thấy thông báo lỗi cho biết auth/operation-not-allowed , hãy kiểm tra để đảm bảo rằng bạn đã bật Đăng nhập bằng Google với tư cách là nhà cung cấp xác thực trong bảng điều khiển Firebase.
  3. Sau khi đăng nhập, ảnh hồ sơ và tên người dùng của bạn sẽ được hiển thị: góc lửa-3.png

9. Viết tin nhắn lên Cloud Firestore

Trong phần này, bạn sẽ ghi một số dữ liệu vào Cloud Firestore để có thể đưa vào giao diện người dùng của ứng dụng. Việc này có thể được thực hiện thủ công với bảng điều khiển Firebase nhưng bạn sẽ thực hiện việc đó trong chính ứng dụng để minh họa cách ghi cơ bản trên Cloud Firestore.

Mô hình dữ liệu

Dữ liệu của Cloud Firestore đượ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 trong cuộc 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à messages .

688d7bc5fb662b57.png

Thêm tin nhắn vào Cloud Firestore

Để lưu trữ tin nhắn trò chuyện do người dùng viết, bạn sẽ sử dụng Cloud 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 của bạn. 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 một đối tượng tin nhắn có nội dung của các trường tin nhắn vào phiên bản Cloud Firestore của bạn trong bộ sưu tập messages . Phương thức add() thêm một tài liệu mới có ID được tạo tự động vào bộ sưu tập.

  1. Quay lại tệp src/app/services/chat.service.ts .
  2. Tìm hàm addMessage .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Adds a text or image message to Cloud Firestore.
addMessage = async(textMessage: string | null, imageUrl: string | null): Promise<void | DocumentReference<DocumentData>> => {
    let data: any;
    try {
      this.user$.subscribe(async (user) => 
      { 
        if(textMessage && textMessage.length > 0) {
          data =  await addDoc(collection(this.firestore, 'messages'), {
            name: user?.displayName,
            text: textMessage,
            profilePicUrl: user?.photoURL,
            timestamp: serverTimestamp(),
            uid: user?.uid
          })}
          else if (imageUrl && imageUrl.length > 0) {
            data =  await addDoc(collection(this.firestore, 'messages'), {
              name: user?.displayName,
              imageUrl: imageUrl,
              profilePicUrl: user?.photoURL,
              timestamp: serverTimestamp(),
              uid: user?.uid
            });
          }
          return data;
        }
      );
    }
    catch(error) {
      console.error('Error writing new message to Firebase Database', error);
      return;
    }
}

Kiểm tra việc gửi tin nhắn

  1. Nếu ứng dụng của bạn vẫn đang được phân phát, hãy làm mới ứng dụng của bạn trong trình duyệt. Nếu không, hãy chạy firebase emulators:start trên dòng lệnh để bắt đầu phân phát ứng dụng từ http://localhost:5000 , sau đó mở ứng dụng đó trong trình duyệt của bạn.
  2. Sau khi đăng nhập, nhập tin nhắn như "Xin chào!", rồi nhấp vào GỬI . Điều này sẽ viết tin nhắn vào Cloud Firestore. Tuy nhiên, bạn sẽ chưa thấy dữ liệu 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 (phần tiếp theo của lớp học lập trình).
  3. Bạn có thể xem thông báo mới được thêm trong Bảng điều khiển Firebase của mình. Mở giao diện người dùng bộ Trình mô phỏng của bạn. Trong phần Xây dựng , nhấp vào Cơ sở dữ liệu Firestore (hoặc nhấp vào đây và bạn sẽ thấy bộ sưu tập tin nhắn cùng với tin nhắn mới được thêm của mình:

6812efe7da395692.png

10. Đọc tin nhắn

Đồng bộ hóa tin nhắn

Để đọc tin nhắn trong ứng dụng, bạn cần thêm một thành phần có thể quan sát sẽ 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ị tin nhắn mới.

Bạn sẽ thêm mã để nghe tin nhắn mới được thêm từ ứng dụng. Trong mã này, bạn sẽ truy xuất ảnh chụp nhanh của bộ sưu tập messages . Bạn sẽ chỉ hiển thị 12 tin nhắn cuối cùng của cuộc trò chuyện để tránh hiển thị lịch sử quá dài khi tải.

  1. Quay lại tệp src/app/services/chat.service.ts .
  2. Tìm hàm loadMessages .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
  // Start listening to the query.
  return collectionData(recentMessagesQuery);
}

Để nghe thông báo trong cơ sở dữ liệu, bạn tạo một truy vấn trên một bộ sưu tập bằng cách sử dụng hàm bộ collection để chỉ định dữ liệu bạn muốn nghe nằm trong bộ sưu tập nào. Trong đoạn mã trên, bạn đang lắng nghe những thay đổi trong messages bộ sưu tập, nơi lưu trữ các tin nhắn trò chuyện. Bạn cũng đang áp dụng giới hạn bằng cách chỉ nghe 12 tin nhắn gần đây nhất bằng cách sử dụng limit(12) và sắp xếp các tin nhắn theo ngày bằng cách sử dụng orderBy('timestamp', 'desc') để nhận được 12 tin nhắn mới nhất.

Hàm collectionData sử dụng ảnh chụp nhanh. Chức năng gọi lại sẽ đượ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. Bạn có thể đọc thêm về điều này trong tài liệu Cloud Firestore .

Kiểm tra việc đồng bộ hóa tin nhắn

  1. Nếu ứng dụng của bạn vẫn đang được phân phát, hãy làm mới ứng dụng của bạn trong trình duyệt. Nếu không, hãy chạy firebase emulators:start trên dòng lệnh để bắt đầu phân phát ứng dụng từ http://localhost:5000 , sau đó mở ứng dụng đó trong trình duyệt của bạn.
  2. Các tin nhắn bạn đã tạo trước đó trong cơ sở dữ liệu sẽ được hiển thị trong Giao diện người dùng FriendlyChat (xem bên dưới). 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.
  3. (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 Firestore của bộ Trình mô phỏng; mọi thay đổi sẽ được phản ánh 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!

góc lửa-2.png

11. Gửi hình ảnh

Bây giờ bạn sẽ thêm tính năng chia sẻ hình ảnh.

Trong khi Cloud Firestore phù hợp để lưu trữ dữ liệu có cấu trúc thì Cloud Storage lại phù hợp hơn để lưu trữ tệp. Cloud Storage cho Firebase là dịch vụ lưu trữ tệp/blob và bạn sẽ sử dụng dịch vụ này để lưu trữ bất kỳ hình ảnh nào mà người dùng chia sẻ bằng ứng dụng của chúng tôi.

Lưu hình ảnh vào Cloud Storage

Đối với lớp học lập trình này, bạn đã thêm cho mình một nút kích hoạt hộp thoại bộ chọn tệp. Sau khi chọn tệp, hàm saveImageMessage sẽ được gọi và bạn có thể nhận được tham chiếu đến tệp đã chọn. Hàm saveImageMessage thực hiện những việc sau:

  1. Tạo tin nhắn trò chuyện "giữ chỗ" trong nguồn cấp dữ liệu trò chuyện để người dùng nhìn thấy hoạt ảnh "Đang tải" khi bạn tải hình ảnh lên.
  2. Tải file ảnh lên Cloud Storage theo đường dẫn sau: /<uid>/<file_name>
  3. Tạo một URL có thể đọc công khai cho tệp hình ảnh.
  4. Cập nhật tin nhắn trò chuyện bằng URL của tệp hình ảnh mới tải lên thay cho hình ảnh tải tạm thời.

Bây giờ bạn sẽ thêm chức năng gửi hình ảnh:

  1. Quay lại file src/chat.service.ts .
  2. Tìm hàm saveImageMessage .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

trò chuyện.service.ts

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - You add a message with a loading icon that will get updated with the shared image.
    const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
    const newImageRef = ref(this.storage, filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    messageRef ?
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    }): null;
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

Kiểm tra gửi hình ảnh

  1. Nếu ứng dụng của bạn vẫn đang được phân phát, hãy làm mới ứng dụng của bạn trong trình duyệt. Nếu không, hãy chạy firebase emulators:start trên dòng lệnh để bắt đầu phân phát ứng dụng từ http://localhost:5000 , sau đó mở ứng dụng đó trong trình duyệt của bạn.
  2. Sau khi đăng nhập, nhấp vào nút tải lên hình ảnh ở phía dưới bên trái góc lửa-4.png và chọn tệp hình ảnh bằng trình chọn tệp. Nếu bạn đang tìm kiếm một hình ảnh thì hãy thoải mái sử dụng hình ảnh ly cà phê đẹp này nhé.
  3. Một thông báo mới sẽ xuất hiện trong giao diện người dùng của ứng dụng cùng với hình ảnh bạn đã chọn: góc lửa-2.png

Nếu bạn thử thêm hình ảnh khi chưa đăng nhập, bạn sẽ thấy lỗi thông báo rằng bạn phải đăng nhập để thêm hình ảnh.

12. Hiển thị thông báo

Bây giờ bạn sẽ thêm hỗ trợ cho thông báo của trình duyệt. Ứng dụng sẽ thông báo cho người dùng khi có tin nhắn mới được đăng trong cuộc trò chuyện. Firebase Cloud Messaging (FCM) là giải pháp nhắn tin đa nền tảng cho phép bạn gửi tin nhắn và thông báo một cách đáng tin cậy mà không mất phí.

Thêm nhân viên dịch vụ FCM

Ứng dụng web cần một nhân viên dịch vụ sẽ nhận và hiển thị thông báo web.

Nhà cung cấp dịch vụ nhắn tin phải được thiết lập khi thêm AngularFire, hãy đảm bảo rằng đoạn mã sau tồn tại trong phần nhập của /angularfire-start/src/app/app.module.ts

provideMessaging(() => {
    return getMessaging();
}),

app/app.module.ts

Nhân viên dịch vụ chỉ cần tải và khởi tạo SDK nhắn tin qua đám mây Firebase, SDK này sẽ đảm nhiệm việc hiển thị thông báo.

Nhận mã thông báo thiết bị FCM

Khi thông báo đã được bật trên thiết bị hoặc trình duyệt, bạn sẽ được cấp mã thông báo thiết bị . Mã thông báo thiết bị này là thứ bạn sử dụng để gửi thông báo đến một thiết bị cụ thể hoặc trình duyệt cụ thể.

Khi người dùng đăng nhập, bạn gọi hàm saveMessagingDeviceToken . Đó là nơi bạn sẽ nhận được mã thông báo thiết bị FCM từ trình duyệt và lưu nó vào Cloud Firestore.

chat.service.ts

  1. Tìm hàm saveMessagingDeviceToken .
  2. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
    try {
      const currentToken = await getToken(this.messaging);
      if (currentToken) {
        console.log('Got FCM device token:', currentToken);
        // Saving the Device Token to Cloud Firestore.
        const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
        await setDoc(tokenRef, { uid: this.auth.currentUser?.uid });
 
        // This will fire when a message is received while the app is in the foreground.
        // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
        onMessage(this.messaging, (message) => {
          console.log(
            'New foreground notification from Firebase Messaging!',
            message.notification
          );
        });
      } else {
        // Need to request permissions to show notifications.
        this.requestNotificationsPermissions();
      }
    } catch(error) {
      console.error('Unable to get messaging token.', error);
    };
}

Tuy nhiên, mã này ban đầu sẽ không hoạt động. Để ứng dụng của bạn có thể truy xuất mã thông báo thiết bị, người dùng cần cấp cho ứng dụng của bạn quyền hiển thị thông báo (bước tiếp theo của lớp học lập trình).

Yêu cầu quyền hiển thị thông báo

Khi người dùng chưa cấp cho ứng dụng của bạn quyền hiển thị thông báo, bạn sẽ không được cấp mã thông báo thiết bị. Trong trường hợp này, bạn gọi phương thức requestPermission() , phương thức này sẽ hiển thị hộp thoại trình duyệt yêu cầu quyền này ( trong các trình duyệt được hỗ trợ ).

8b9d0c66dc36153d.png

  1. Quay lại tệp src/app/services/chat.service.ts .
  2. Tìm hàm requestNotificationsPermissions .
  3. Thay thế toàn bộ chức năng bằng đoạn mã sau.

chat.service.ts

// Requests permissions to show notifications.
requestNotificationsPermissions = async () => {
    console.log('Requesting notifications permission...');
    const permission = await Notification.requestPermission();
    
    if (permission === 'granted') {
      console.log('Notification permission granted.');
      // Notification permission granted.
      await this.saveMessagingDeviceToken();
    } else {
      console.log('Unable to get permission to notify.');
    }
}

Nhận mã thông báo thiết bị của bạn

  1. Nếu ứng dụng của bạn vẫn đang được phân phát, hãy làm mới ứng dụng của bạn trong trình duyệt. Nếu không, hãy chạy firebase emulators:start trên dòng lệnh để bắt đầu phân phát ứng dụng từ http://localhost:5000 , sau đó mở ứng dụng đó trong trình duyệt của bạn.
  2. Sau khi đăng nhập, hộp thoại cấp phép thông báo sẽ xuất hiện: bd3454e6dbfb6723.png
  3. Nhấp vào Cho phép .
  4. Mở bảng điều khiển JavaScript của trình duyệt của bạn. Bạn sẽ thấy thông báo sau: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Sao chép mã thông báo thiết bị của bạn. Bạn sẽ cần nó cho giai đoạn tiếp theo của lớp học lập trình.

Gửi thông báo tới thiết bị của bạn

Bây giờ bạn đã có mã thông báo thiết bị của mình, bạn có thể gửi thông báo.

  1. Mở tab Nhắn tin qua đám mây của bảng điều khiển Firebase .
  2. Nhấp vào "Thông báo mới"
  3. Nhập tiêu đề thông báo và văn bản thông báo.
  4. Ở bên phải màn hình, nhấp vào "gửi tin nhắn kiểm tra"
  5. Nhập mã thông báo thiết bị bạn đã sao chép từ bảng điều khiển JavaScript của trình duyệt, sau đó nhấp vào dấu cộng ("+")
  6. Nhấp vào "kiểm tra"

Nếu ứng dụng của bạn chạy ở nền trước, bạn sẽ thấy thông báo trong bảng điều khiển JavaScript.

Nếu ứng dụng của bạn chạy ở chế độ nền thì thông báo sẽ xuất hiện trong trình duyệt của bạn, như trong ví dụ này:

de79e8638a45864c.png

13. Quy tắc bảo mật của Cloud Firestore

Xem các quy tắc bảo mật cơ sở dữ liệu

Cloud Firestore sử dụng ngôn ngữ quy tắc cụ thể để xác định quyền truy cập, bảo mật và xác thực dữ liệu.

Khi thiết lập dự án Firebase ở đầu lớp học lập trình này, bạn đã chọn sử dụng quy tắc bảo mật mặc định của "Chế độ thử nghiệm" để không hạn chế quyền truy cập vào kho dữ liệu. Trong bảng điều khiển Firebase , trong tab Quy tắc của phần Cơ sở dữ liệu , bạn có thể xem và sửa đổi các quy tắc này.

Ngay bây giờ, bạn sẽ thấy các quy tắc mặc định không hạn chế quyền truy cập vào kho dữ liệu. Điều này có nghĩa là bất kỳ người dùng nào cũng có thể đọc và ghi vào bất kỳ bộ sưu tập nào trong kho dữ liệu của bạn.

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

Bạn sẽ cập nhật các quy tắc để hạn chế mọi thứ bằng cách sử dụng các quy tắc sau:

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

Các quy tắc bảo mật sẽ tự động cập nhật vào bộ Trình mô phỏng của bạn.

Xem quy tắc bảo mật của Cloud Storage

Cloud Storage cho Firebase sử dụng ngôn ngữ quy tắc cụ thể để xác định quyền truy cập, bảo mật và xác thực dữ liệu.

Khi thiết lập dự án Firebase ở phần đầu của lớp học lập trình này, bạn đã chọn sử dụng quy tắc bảo mật Cloud Storage mặc định chỉ cho phép những người dùng đã xác thực sử dụng Cloud Storage. Trong bảng điều khiển Firebase , trong tab Quy tắc của phần Lưu trữ , bạn có thể xem và sửa đổi các quy tắc. Bạn sẽ thấy quy tắc mặc định cho phép mọi người dùng đã đăng nhập đọc và ghi bất kỳ tệp nào trong nhóm lưu trữ của bạn.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Bạn sẽ cập nhật các quy tắc để thực hiện những việc sau:

  • Cho phép mỗi người dùng chỉ ghi vào các thư mục cụ thể của riêng họ
  • Cho phép mọi người đọc từ Cloud Storage
  • Đảm bảo rằng các tập tin được tải lên là hình ảnh
  • Hạn chế kích thước của hình ảnh có thể được tải lên tối đa 5 MB

Điều này có thể được thực hiện bằng cách sử dụng các quy tắc sau:

lưu trữ.rules

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

14. Triển khai ứng dụng của bạn bằng Firebase Hosting

Firebase cung cấp dịch vụ lưu trữ để phục vụ nội dung và ứng dụng web của bạn. Bạn có thể triển khai các tệp của mình lên Dịch vụ lưu trữ Firebase bằng Firebase CLI. Trước khi triển khai, bạn cần chỉ định trong tệp firebase.json những tệp cục bộ nào sẽ được triển khai. Đối với lớp học lập trình này, bạn đã thực hiện việc này vì bước này là bắt buộc để phân phát các tệp của chúng tôi trong lớp học lập trình này. Cài đặt lưu trữ được chỉ định trong thuộc tính hosting :

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

Các cài đặt này cho CLI biết rằng bạn muốn triển khai tất cả các tệp trong thư mục ./public ( "public": "./public" ).

  1. Đảm bảo rằng dòng lệnh của bạn đang truy cập vào thư mục angularfire-start bộ của ứng dụng.
  2. Triển khai các tệp của bạn vào dự án Firebase bằng cách chạy lệnh sau:
ng deploy

Sau đó chọn tùy chọn Firebase và làm theo lời nhắc trong dòng lệnh.

  1. Bảng điều khiển sẽ hiển thị như sau:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Truy cập ứng dụng web hiện được lưu trữ đầy đủ trên CDN toàn cầu bằng cách sử dụng Dịch vụ lưu trữ Firebase tại hai tên miền phụ Firebase của riêng bạn:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Ngoài ra, bạn có thể chạy firebase open hosting:site trong dòng lệnh.

Hãy truy cập tài liệu để tìm hiểu thêm về cách hoạt động của Firebase Hosting .

Đi tới phần Lưu trữ bảng điều khiển Firebase trong dự án của bạn để xem thông tin và công cụ lưu trữ hữu ích, bao gồm lịch sử triển khai, chức năng quay lại các phiên bản trước của ứng dụng và quy trình làm việc để thiết lập miền tùy chỉnh.

15. Xin chúc mừng!

Bạn đã sử dụng Firebase để xây dựng ứng dụng web trò chuyện theo thời gian thực!

Những gì bạn đã đề cập

  • Xác thực Firebase
  • Cửa hàng đám mây
  • SDK Firebase cho bộ nhớ đám mây
  • Nhắn tin qua đám mây Firebase
  • Giám sát hiệu suất Firebase
  • Lưu trữ căn cứ hỏa lực

Bước tiếp theo

Tìm hiểu thêm

16. [Tùy chọn] Thực thi bằng Kiểm tra ứng dụng

Kiểm tra ứng dụng Firebase giúp bảo mật dịch vụ của bạn khỏi lưu lượng truy cập không mong muốn và giúp bảo vệ phần phụ trợ của bạn khỏi bị lạm dụng. Trong bước này, bạn sẽ thêm xác thực thông tin xác thực và chặn ứng dụng khách trái phép bằng Kiểm tra ứng dụng và reCAPTCHA Enterprise .

Trước tiên, bạn cần bật Kiểm tra ứng dụng và reCaptcha.

Kích hoạt reCaptcha Enterprise

  1. Trong bảng điều khiển Đám mây, tìm và chọn reCaptcha Enterprise trong phần Bảo mật.
  2. Kích hoạt dịch vụ như được nhắc và nhấp vào Create Key .
  3. Nhập tên hiển thị theo lời nhắc và chọn Trang web làm loại nền tảng của bạn.
  4. Thêm các URL đã triển khai của bạn vào danh sách Miền và đảm bảo rằng tùy chọn "Sử dụng hộp kiểm thử thách" không được chọn .
  5. Nhấp vào Tạo khóa và lưu trữ khóa đã tạo ở đâu đó để giữ an toàn. Bạn sẽ cần nó sau này trong bước này.

Bật kiểm tra ứng dụng

  1. Trong bảng điều khiển Firebase, tìm phần Xây dựng ở bảng điều khiển bên trái.
  2. Nhấp vào Kiểm tra ứng dụng , sau đó nhấp vào tab Phương thức đăng nhập để điều hướng đến Kiểm tra ứng dụng .
  3. Nhấp vào Đăng ký và nhập khóa reCaptcha Enterprise của bạn khi được nhắc, sau đó nhấp vào Lưu .
  4. Trong Chế độ xem API, chọn Lưu trữ và nhấp vào Thực thi . Làm tương tự với Cloud Firestore .

Kiểm tra ứng dụng bây giờ sẽ được thực thi! Hãy làm mới ứng dụng của bạn và thử xem hoặc gửi tin nhắn trò chuyện. Bạn sẽ nhận được thông báo lỗi:

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

Điều này có nghĩa là Kiểm tra ứng dụng đang chặn các yêu cầu không được xác thực theo mặc định. Bây giờ hãy thêm xác thực vào ứng dụng của bạn.

Điều hướng đến tệp environment.ts của bạn và thêm reCAPTCHAEnterpriseKey vào đối tượng environment .

export const environment = {
  firebase: {
    apiKey: 'API_KEY',
    authDomain: 'PROJECT_ID.firebaseapp.com',
    databaseURL: 'https://PROJECT_ID.firebaseio.com',
    projectId: 'PROJECT_ID',
    storageBucket: 'PROJECT_ID.appspot.com',
    messagingSenderId: 'SENDER_ID',
    appId: 'APP_ID',
    measurementId: 'G-MEASUREMENT_ID',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

Thay thế giá trị của key bằng mã thông báo reCaptcha Enterprise của bạn.

Sau đó, điều hướng đến tệp app.module.ts và thêm các mục nhập sau:

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

Trong cùng một tệp app.module.ts , hãy thêm phần khai báo biến toàn cục sau:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

Trong quá trình nhập, hãy thêm hoạt động khởi tạo Kiểm tra ứng dụng bằng ReCaptchaEnterpriseProvider và đặt isTokenAutoRefreshEnabled thành true để cho phép mã thông báo tự động làm mới.

imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
  provider: new ReCaptchaEnterpriseProvider(
  environment.reCAPTCHAEnterpriseKey.key
  ),
  isTokenAutoRefreshEnabled: true,
  });
  if (location.hostname === 'localhost') {
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
  }
  return appCheck;
}),

Để cho phép thử nghiệm cục bộ, hãy đặt self.FIREBASE_APPCHECK_DEBUG_TOKEN thành true . Khi bạn làm mới ứng dụng của mình trong localhost , thao tác này sẽ ghi lại mã thông báo gỡ lỗi trong bảng điều khiển tương tự như:

App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.

Bây giờ, hãy chuyển đến Chế độ xem ứng dụng của Kiểm tra ứng dụng trong bảng điều khiển Firebase.

Nhấp vào menu mục bổ sung và chọn Quản lý mã thông báo gỡ lỗi .

Sau đó, nhấp vào Thêm mã thông báo gỡ lỗi và dán mã thông báo gỡ lỗi từ bảng điều khiển của bạn như được nhắc.

Điều hướng đến tệp chat.service.ts và thêm nội dung nhập sau:

import { AppCheck } from '@angular/fire/app-check';

Trong cùng một tệp chat.service.ts , hãy đưa Kiểm tra ứng dụng cùng với các dịch vụ Firebase khác.

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...

Chúc mừng! Kiểm tra ứng dụng bây giờ sẽ hoạt động trong ứng dụng của bạn.