Laboratorium programowania internetowego AngularFire

1. Przegląd

Podczas tych zajęć z programowania dowiesz się, jak używać AngularFire do tworzenia aplikacji internetowych, wdrażając klienta czatu przy użyciu produktów i usług Firebase.

angularfire-2.png

Czego się dowiesz

  • Zbuduj aplikację internetową przy użyciu Angular i Firebase.
  • Synchronizuj dane za pomocą Cloud Firestore i Cloud Storage dla Firebase.
  • Uwierzytelnij swoich użytkowników za pomocą uwierzytelniania Firebase.
  • Wdróż swoją aplikację internetową w Hostingu Firebase.
  • Wysyłaj powiadomienia za pomocą Firebase Cloud Messaging.
  • Zbieraj dane dotyczące wydajności aplikacji internetowej.

Co będziesz potrzebował

  • Wybrany edytor IDE/tekstu, taki jak WebStorm , Atom , Sublime lub VS Code
  • Menedżer pakietów npm , który zwykle jest dostarczany z Node.js
  • Terminal/konsola
  • Wybrana przeglądarka, np. Chrome
  • Przykładowy kod ćwiczeń z programowania (zobacz następny krok ćwiczeń z kodowania, aby dowiedzieć się, jak uzyskać kod).

2. Pobierz przykładowy kod

Sklonuj repozytorium GitHub Codelab z wiersza poleceń:

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

Alternatywnie, jeśli nie masz zainstalowanego gita, możesz pobrać repozytorium jako plik ZIP .

Zaimportuj aplikację startową

Używając swojego IDE, otwórz lub zaimportuj katalog 📁 angularfire-start ze sklonowanego repozytorium. Ten 📁 katalog angularfire-start zawiera kod startowy laboratorium kodowania, które będzie w pełni funkcjonalną aplikacją internetową do czatowania.

3. Utwórz i skonfiguruj projekt Firebase

Utwórz projekt Firebase

  1. Zaloguj się do Firebase .
  2. W konsoli Firebase kliknij Dodaj projekt , a następnie nazwij swój projekt Firebase FriendlyChat . Zapamiętaj identyfikator projektu Firebase.
  3. Odznacz opcję Włącz Google Analytics dla tego projektu
  4. Kliknij opcję Utwórz projekt .

Aplikacja, którą zamierzasz zbudować, korzysta z produktów Firebase dostępnych dla aplikacji internetowych:

  • Uwierzytelnianie Firebase , aby umożliwić użytkownikom łatwe logowanie się do Twojej aplikacji.
  • Cloud Firestore do zapisywania uporządkowanych danych w chmurze i otrzymywania natychmiastowych powiadomień o zmianach danych.
  • Cloud Storage dla Firebase do zapisywania plików w chmurze.
  • Hosting Firebase do hostowania i obsługi Twoich zasobów.
  • Firebase Cloud Messaging do wysyłania powiadomień push i wyświetlania wyskakujących powiadomień przeglądarki.
  • Monitorowanie wydajności Firebase w celu gromadzenia danych dotyczących wydajności użytkowników Twojej aplikacji.

Niektóre z tych produktów wymagają specjalnej konfiguracji lub wymagają włączenia za pomocą konsoli Firebase.

Dodaj aplikację internetową Firebase do projektu

  1. Kliknij ikonę sieci 58d6543a156e56f9.png aby utworzyć nową aplikację internetową Firebase.
  2. Zarejestruj aplikację pod pseudonimem Friendly Chat , a następnie zaznacz pole obok Skonfiguruj także hosting Firebase dla tej aplikacji . Kliknij opcję Zarejestruj aplikację .
  3. W następnym kroku zobaczysz obiekt konfiguracyjny. Skopiuj sam obiekt JS (nie otaczający go kod HTML) do pliku firebase-config.js

Zarejestruj zrzut ekranu aplikacji internetowej

Włącz logowanie Google do uwierzytelniania Firebase

Aby umożliwić użytkownikom logowanie się do aplikacji internetowej przy użyciu kont Google, użyj metody logowania Google .

Musisz włączyć logowanie Google :

  1. W konsoli Firebase znajdź sekcję Kompilacja w lewym panelu.
  2. Kliknij opcję Uwierzytelnianie , a następnie kliknij kartę Metoda logowania (lub kliknij tutaj , aby przejść bezpośrednio tam).
  3. Włącz dostawcę logowania Google , a następnie kliknij Zapisz .
  4. Ustaw publiczną nazwę swojej aplikacji na Przyjazny Czat i wybierz z menu rozwijanego adres e-mail pomocy technicznej projektu .
  5. Skonfiguruj ekran zgody OAuth w Google Cloud Console i dodaj logo:

d89fb3873b5d36ae.png

Włącz Cloud Firestore

Aplikacja internetowa korzysta z Cloud Firestore do zapisywania wiadomości czatu i odbierania nowych wiadomości czatu.

Musisz włączyć Cloud Firestore:

  1. W sekcji Kompilacja konsoli Firebase kliknij Baza danych Firestore .
  2. Kliknij opcję Utwórz bazę danych w panelu Cloud Firestore.

729991a081e7cd5.png

  1. Wybierz opcję Uruchom w trybie testowym , a następnie po zapoznaniu się z zastrzeżeniem dotyczącym zasad bezpieczeństwa kliknij Dalej .

Tryb testowy zapewnia możliwość swobodnego zapisu do bazy danych podczas programowania. W dalszej części tego ćwiczenia z programowania zadbasz o większe bezpieczeństwo naszej bazy danych.

77e4986cbeaf9dee.png

  1. Ustaw lokalizację, w której przechowywane są dane Cloud Firestore. Możesz pozostawić to ustawienie domyślne lub wybrać region blisko siebie. Kliknij Gotowe , aby udostępnić Firestore.

9f2bb0d4e7ca49c7.png

Włącz przechowywanie w chmurze

Aplikacja internetowa korzysta z Cloud Storage dla Firebase do przechowywania, przesyłania i udostępniania zdjęć.

Musisz włączyć przechowywanie w chmurze:

  1. W sekcji Kompilacja konsoli Firebase kliknij opcję Pamięć .
  2. Jeśli nie ma przycisku Rozpocznij , oznacza to, że przechowywanie w chmurze jest już włączone i nie musisz wykonywać poniższych kroków.
  3. Kliknij opcję Rozpocznij .
  4. Przeczytaj zastrzeżenie dotyczące reguł bezpieczeństwa Twojego projektu Firebase, a następnie kliknij Dalej .

Przy domyślnych regułach bezpieczeństwa każdy uwierzytelniony użytkownik może zapisywać wszystko w Cloud Storage. W dalszej części tego ćwiczenia z programowania zadbasz o większe bezpieczeństwo naszego magazynu.

62f1afdcd1260127.png

  1. Lokalizacja Cloud Storage jest wstępnie wybrana z tym samym regionem, który wybrałeś dla swojej bazy danych Cloud Firestore. Kliknij Gotowe, aby zakończyć konfigurację.

1d7f49ebaddb32fc.png

4. Zainstaluj interfejs wiersza poleceń Firebase

Interfejs wiersza poleceń Firebase (CLI) umożliwia używanie Firebase Hosting do lokalnego udostępniania aplikacji internetowej, a także wdrażania aplikacji internetowej w projekcie Firebase.

  1. Zainstaluj interfejs CLI, uruchamiając następującą komendę npm:
npm -g install firebase-tools
  1. Sprawdź, czy interfejs CLI został poprawnie zainstalowany, uruchamiając następującą komendę:
firebase --version

Upewnij się, że wersja Firebase CLI to v4.1.0 lub nowsza.

  1. Autoryzuj interfejs CLI Firebase, uruchamiając następujące polecenie:
firebase login

Skonfigurowałeś szablon aplikacji internetowej do pobierania konfiguracji aplikacji dla Firebase Hosting z lokalnego katalogu aplikacji (repozytorium sklonowanego wcześniej podczas ćwiczeń z programowania). Aby jednak pobrać konfigurację, musisz powiązać aplikację z projektem Firebase.

  1. Upewnij się, że wiersz poleceń uzyskuje dostęp do lokalnego katalogu angularfire-start Twojej aplikacji.
  2. Powiąż swoją aplikację z projektem Firebase, uruchamiając następujące polecenie:
firebase use --add
  1. Po wyświetleniu monitu wybierz identyfikator projektu , a następnie nadaj projektowi Firebase alias.

Alias ​​jest przydatny, jeśli masz wiele środowisk (produkcyjnych, testowych itp.). Jednak w tym ćwiczeniu z kodowania użyjmy po prostu aliasu default .

  1. Postępuj zgodnie z pozostałymi instrukcjami w wierszu poleceń.

5. Zainstaluj AngularFire

Przed uruchomieniem projektu upewnij się, że masz skonfigurowane Angular CLI i AngularFire.

  1. W konsoli uruchom następujące polecenie:
npm install -g @angular/cli
  1. Następnie w konsoli z katalogu angularfire-start uruchom następującą komendę Angular CLI:
ng add @angular/fire

Spowoduje to zainstalowanie wszystkich niezbędnych zależności dla Twojego projektu.

  1. Po wyświetleniu monitu wybierz funkcje skonfigurowane w konsoli Firebase ( ng deploy -- hosting , Authentication , Firestore , Cloud Functions (callable) , Cloud Messaging , Cloud Storage ) i postępuj zgodnie z instrukcjami wyświetlanymi na konsoli.

6. Uruchom aplikację startową lokalnie

Po zaimportowaniu i skonfigurowaniu projektu możesz przystąpić do pierwszego uruchomienia aplikacji internetowej.

  1. W konsoli z katalogu angularfire-start uruchom następującą komendę Firebase CLI:
firebase emulators:start
  1. Twój wiersz poleceń powinien wyświetlić następującą odpowiedź:
✔  hosting: Local server: http://localhost:5000

Używasz emulatora Firebase Hosting do lokalnego udostępniania naszej aplikacji. Aplikacja internetowa powinna być teraz dostępna pod adresem http://localhost:5000 . Udostępniane są wszystkie pliki znajdujące się w podkatalogu src .

  1. Za pomocą przeglądarki otwórz aplikację pod adresem http://localhost:5000 .

Powinieneś zobaczyć interfejs użytkownika aplikacji FriendlyChat, który (jeszcze!) nie działa:

angularfire-2.png

Aplikacja nie może teraz nic zrobić, ale z Twoją pomocą wkrótce to zrobi! Do tej pory zaprojektowałeś tylko interfejs użytkownika.

Stwórzmy teraz czat w czasie rzeczywistym!

7. Zaimportuj i skonfiguruj Firebase

Skonfiguruj Firebase

Musisz skonfigurować pakiet SDK Firebase, aby poinformować go, jakiego projektu Firebase używasz.

  1. Przejdź do ustawień projektu w konsoli Firebase
  2. Na karcie „Twoje aplikacje” wybierz pseudonim aplikacji, dla której potrzebujesz obiektu konfiguracyjnego.
  3. Wybierz opcję „Konfiguracja” w panelu fragmentu kodu SDK Firebase.

Przekonasz się, że wygenerowano dla Ciebie plik środowiska /angularfire-start/src/environments/environment.ts .

  1. Skopiuj fragment obiektu konfiguracyjnego, a następnie dodaj go do 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",
  },
};

Zaimportuj AngularFire

Przekonasz się, że funkcje wybrane w konsoli zostały automatycznie przekierowane w pliku /angularfire-start/src/app/app.module.ts . Dzięki temu Twoja aplikacja może korzystać z funkcji Firebase. Aby jednak móc rozwijać się w środowisku lokalnym, należy je połączyć, aby móc korzystać z pakietu emulatorów.

  1. W /angularfire-start/src/app/app.module.ts znajdź sekcję imports i zmodyfikuj udostępnione funkcje, aby połączyć się z pakietem emulatorów w środowiskach nieprodukcyjnych.
// ...

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

Podczas tych zajęć z programowania będziesz korzystać z uwierzytelniania Firebase, Cloud Firestore, przechowywania w chmurze, przesyłania wiadomości w chmurze i monitorowania wydajności, więc importujesz wszystkie ich biblioteki. W przyszłych aplikacjach upewnij się, że importujesz tylko te części Firebase, których potrzebujesz, aby skrócić czas ładowania aplikacji.

8. Skonfiguruj logowanie użytkownika

AngularFire powinien być teraz gotowy do użycia, ponieważ został zaimportowany i zainicjowany w app.module.ts . Zamierzasz teraz zaimplementować logowanie użytkownika przy użyciu uwierzytelniania Firebase .

Uwierzytelnij swoich użytkowników za pomocą logowania Google

W aplikacji, gdy użytkownik kliknie przycisk Zaloguj się przez Google , uruchamiana jest funkcja login . (Już to skonfigurowałeś!) Na potrzeby tych zajęć z programowania chcesz autoryzować Firebase do używania Google jako dostawcy tożsamości. Użyjesz wyskakującego okienka, ale w Firebase dostępnych jest kilka innych metod .

  1. W katalogu angularfire-start , w podkatalogu /src/app/services/ otwórz chat.service.ts .
  2. Znajdź funkcję login .
  3. Zastąp całą funkcję następującym kodem.

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;
    })
}

Funkcja logout uruchamiana jest po kliknięciu przez użytkownika przycisku Wyloguj .

  1. Wróć do pliku src/app/services/chat.service.ts .
  2. Znajdź funkcję logout .
  3. Zastąp całą funkcję następującym kodem.

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);
    })
}

Śledź stan uwierzytelnienia

Aby odpowiednio zaktualizować nasz interfejs użytkownika, potrzebujesz sposobu na sprawdzenie, czy użytkownik jest zalogowany, czy wylogowany. Dzięki uwierzytelnianiu Firebase możesz pobrać obserwowalny stan użytkownika, który będzie wyzwalany za każdym razem, gdy zmieni się stan uwierzytelnienia.

  1. Wróć do pliku src/app/services/chat.service.ts .
  2. Znajdź przypisanie zmiennej user$ .
  3. Zamień całe zadanie na poniższy kod.

chat.service.ts

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

Powyższy kod wywołuje funkcję AngularFire user , która zwraca obserwowalnego użytkownika. Będzie wyzwalane za każdym razem, gdy zmieni się stan uwierzytelnienia (kiedy użytkownik się zaloguje lub wyloguje). W tym momencie zaktualizujesz interfejs użytkownika, aby przekierowywał, wyświetlał użytkownika w nagłówku nawigacji i tak dalej. Wszystkie te części interfejsu użytkownika zostały już wdrożone.

Przetestuj logowanie do aplikacji

  1. Jeśli Twoja aplikacja jest nadal udostępniana, odśwież ją w przeglądarce. W przeciwnym razie uruchom firebase emulators:start w wierszu poleceń, aby rozpocząć udostępnianie aplikacji z adresu http://localhost:5000 , a następnie otwórz ją w przeglądarce.
  2. Zaloguj się do aplikacji za pomocą przycisku logowania i swojego konta Google. Jeśli zobaczysz komunikat o błędzie z informacją, że auth/operation-not-allowed , ​​sprawdź, czy w konsoli Firebase włączyłeś Logowanie Google jako dostawcę uwierzytelniania.
  3. Po zalogowaniu powinno wyświetlić się Twoje zdjęcie profilowe i nazwa użytkownika: angularfire-3.png

9. Napisz wiadomości do Cloud Firestore

W tej sekcji zapiszesz pewne dane w Cloud Firestore, aby móc wypełnić interfejs użytkownika aplikacji. Można to zrobić ręcznie za pomocą konsoli Firebase , ale zrobisz to w samej aplikacji, aby zademonstrować podstawowy zapis w Cloud Firestore.

Model danych

Dane Cloud Firestore są podzielone na kolekcje, dokumenty, pola i podzbiory. Każdą wiadomość na czacie będziesz przechowywać jako dokument w kolekcji najwyższego poziomu zwanej messages .

688d7bc5fb662b57.png

Dodaj wiadomości do Cloud Firestore

Do przechowywania wiadomości czatu napisanych przez użytkowników użyjesz Cloud Firestore .

W tej sekcji dodasz funkcję umożliwiającą użytkownikom zapisywanie nowych wiadomości w Twojej bazie danych. Użytkownik klikający przycisk WYŚLIJ uruchomi poniższy fragment kodu. Dodaje obiekt wiadomości z zawartością pól wiadomości do instancji Cloud Firestore w kolekcji messages . Metoda add() dodaje do kolekcji nowy dokument z automatycznie wygenerowanym identyfikatorem.

  1. Wróć do pliku src/app/services/chat.service.ts .
  2. Znajdź funkcję addMessage .
  3. Zastąp całą funkcję następującym kodem.

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;
    }
}

Testuj wysyłanie wiadomości

  1. Jeśli Twoja aplikacja jest nadal udostępniana, odśwież ją w przeglądarce. W przeciwnym razie uruchom firebase emulators:start w wierszu poleceń, aby rozpocząć udostępnianie aplikacji z adresu http://localhost:5000 , a następnie otwórz ją w przeglądarce.
  2. Po zalogowaniu wpisz wiadomość typu „Hej!”, a następnie kliknij WYŚLIJ . Spowoduje to zapisanie wiadomości w Cloud Firestore. Jednak nie zobaczysz jeszcze danych w swojej rzeczywistej aplikacji internetowej, ponieważ nadal musisz zaimplementować pobieranie danych (następna sekcja ćwiczeń z programowania).
  3. Nowo dodaną wiadomość możesz zobaczyć w konsoli Firebase. Otwórz interfejs użytkownika pakietu emulatorów. W sekcji Kompilacja kliknij Baza danych Firestore (lub kliknij tutaj , a powinieneś zobaczyć kolekcję wiadomości z nowo dodaną wiadomością:

6812efe7da395692.png

10. Czytaj wiadomości

Synchronizuj wiadomości

Aby czytać wiadomości w aplikacji, musisz dodać element obserwowalny, który będzie uruchamiany w przypadku zmiany danych, a następnie utworzyć element interfejsu użytkownika, który będzie wyświetlał nowe wiadomości.

Dodasz kod, który nasłuchuje nowo dodanych wiadomości z aplikacji. W tym kodzie pobierzesz migawkę kolekcji messages . Wyświetlisz tylko 12 ostatnich wiadomości czatu, aby uniknąć wyświetlania bardzo długiej historii po załadowaniu.

  1. Wróć do pliku src/app/services/chat.service.ts .
  2. Znajdź funkcję loadMessages .
  3. Zastąp całą funkcję następującym kodem.

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);
}

Aby odsłuchać wiadomości w bazie danych, utwórz zapytanie dotyczące kolekcji, korzystając z funkcji collection , aby określić, w której kolekcji znajdują się dane, których chcesz odsłuchać. W powyższym kodzie nasłuchujesz zmian zachodzących w messages kolekcji, w której przechowywane są wiadomości czatu. Stosujesz także limit, odsłuchując tylko 12 ostatnich wiadomości za pomocą limit(12) i porządkując wiadomości według daty za pomocą orderBy('timestamp', 'desc') , aby uzyskać 12 najnowszych wiadomości.

Funkcja collectionData wykorzystuje migawki pod maską. Funkcja wywołania zwrotnego zostanie uruchomiona w przypadku jakichkolwiek zmian w dokumentach pasujących do zapytania. Może się tak zdarzyć, jeśli wiadomość zostanie usunięta, zmodyfikowana lub dodana. Więcej na ten temat możesz przeczytać w dokumentacji Cloud Firestore .

Przetestuj synchronizację wiadomości

  1. Jeśli Twoja aplikacja jest nadal udostępniana, odśwież ją w przeglądarce. W przeciwnym razie uruchom firebase emulators:start w wierszu poleceń, aby rozpocząć udostępnianie aplikacji z adresu http://localhost:5000 , a następnie otwórz ją w przeglądarce.
  2. Wiadomości, które utworzyłeś wcześniej w bazie danych, powinny zostać wyświetlone w interfejsie FriendlyChat (patrz poniżej). Zapraszam do pisania nowych wiadomości; powinny pojawić się natychmiast.
  3. (Opcjonalnie) Możesz spróbować ręcznie usunąć, zmodyfikować lub dodać nowe wiadomości bezpośrednio w sekcji Firestore pakietu emulatorów; wszelkie zmiany powinny zostać odzwierciedlone w interfejsie użytkownika.

Gratulacje! Czytasz dokumenty Cloud Firestore w swojej aplikacji!

angularfire-2.png

11. Wyślij obrazy

Teraz dodasz funkcję udostępniania obrazów.

Podczas gdy Cloud Firestore dobrze nadaje się do przechowywania danych strukturalnych, Cloud Storage lepiej nadaje się do przechowywania plików. Cloud Storage dla Firebase to usługa przechowywania plików/blobów, której będziesz używać do przechowywania wszelkich obrazów udostępnianych przez użytkownika za pomocą naszej aplikacji.

Zapisuj obrazy w chmurze

Na potrzeby tego ćwiczenia z kodowania dodałeś już przycisk uruchamiający okno dialogowe wyboru pliku. Po wybraniu pliku wywoływana jest funkcja saveImageMessage , dzięki której można uzyskać referencję do wybranego pliku. Funkcja saveImageMessage realizuje następujące zadania:

  1. Tworzy „zastępczą” wiadomość na czacie w kanale czatu, dzięki czemu użytkownicy widzą animację „Ładowanie” podczas przesyłania obrazu.
  2. Przesyła plik obrazu do Cloud Storage pod następującą ścieżką: /<uid>/<file_name>
  3. Generuje publicznie czytelny adres URL pliku obrazu.
  4. Aktualizuje wiadomość czatu o adres URL nowo przesłanego pliku obrazu zamiast tymczasowego obrazu ładującego.

Teraz dodasz funkcję wysyłania obrazu:

  1. Wróć do pliku src/chat.service.ts .
  2. Znajdź funkcję saveImageMessage .
  3. Zastąp całą funkcję następującym kodem.

chat.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);
  }
}

Przetestuj wysyłanie obrazów

  1. Jeśli Twoja aplikacja jest nadal udostępniana, odśwież ją w przeglądarce. W przeciwnym razie uruchom firebase emulators:start w wierszu poleceń, aby rozpocząć udostępnianie aplikacji z adresu http://localhost:5000 , a następnie otwórz ją w przeglądarce.
  2. Po zalogowaniu kliknij przycisk przesyłania obrazu w lewym dolnym rogu angularfire-4.png i wybierz plik obrazu za pomocą selektora plików. Jeśli szukasz obrazu, możesz użyć tego ładnego zdjęcia filiżanki kawy .
  3. W interfejsie aplikacji powinna pojawić się nowa wiadomość z wybranym obrazem: angularfire-2.png

Jeśli spróbujesz dodać obraz, nie będąc zalogowanym, powinien pojawić się komunikat o błędzie informujący, że musisz się zalogować, aby dodać obrazy.

12. Pokaż powiadomienia

Teraz dodasz obsługę powiadomień przeglądarki. Aplikacja powiadomi użytkowników, gdy na czacie pojawią się nowe wiadomości. Firebase Cloud Messaging (FCM) to wieloplatformowe rozwiązanie do przesyłania wiadomości, które umożliwia niezawodne i bezpłatne dostarczanie wiadomości i powiadomień.

Dodaj pracownika serwisu FCM

Aplikacja internetowa potrzebuje pracownika usługi , który będzie odbierał i wyświetlał powiadomienia internetowe.

Dostawca wiadomości powinien być już skonfigurowany po dodaniu AngularFire. Upewnij się, że w sekcji importów pliku /angularfire-start/src/app/app.module.ts istnieje następujący kod

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

app/app.module.ts

Pracownik serwisu musi po prostu załadować i zainicjować pakiet SDK Firebase Cloud Messaging, który zajmie się wyświetlaniem powiadomień.

Zdobądź tokeny urządzeń FCM

Po włączeniu powiadomień na urządzeniu lub w przeglądarce otrzymasz token urządzenia . Token urządzenia służy do wysyłania powiadomień do konkretnego urządzenia lub konkretnej przeglądarki.

Kiedy użytkownik się loguje, wywołujesz funkcję saveMessagingDeviceToken . Tam otrzymasz token urządzenia FCM z przeglądarki i zapiszesz go w Cloud Firestore.

chat.service.ts

  1. Znajdź funkcję saveMessagingDeviceToken .
  2. Zastąp całą funkcję następującym kodem.

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);
    };
}

Jednak ten kod nie będzie początkowo działać. Aby aplikacja mogła pobrać token urządzenia, użytkownik musi przyznać aplikacji uprawnienia do wyświetlania powiadomień (następny krok ćwiczeń z programowania).

Poproś o uprawnienia do wyświetlania powiadomień

Jeśli użytkownik nie udzielił jeszcze Twojej aplikacji uprawnień do wyświetlania powiadomień, nie otrzymasz tokenu urządzenia. W tym przypadku wywołujesz metodę requestPermission() , która wyświetli okno dialogowe przeglądarki z pytaniem o to pozwolenie ( w obsługiwanych przeglądarkach ).

8b9d0c66dc36153d.png

  1. Wróć do pliku src/app/services/chat.service.ts .
  2. Znajdź funkcję requestNotificationsPermissions .
  3. Zastąp całą funkcję następującym kodem.

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.');
    }
}

Zdobądź token urządzenia

  1. Jeśli Twoja aplikacja jest nadal udostępniana, odśwież ją w przeglądarce. W przeciwnym razie uruchom firebase emulators:start w wierszu poleceń, aby rozpocząć udostępnianie aplikacji z adresu http://localhost:5000 , a następnie otwórz ją w przeglądarce.
  2. Po zalogowaniu powinno pojawić się okno uprawnień do powiadomień: bd3454e6dbfb6723.png
  3. Kliknij Zezwalaj .
  4. Otwórz konsolę JavaScript w swojej przeglądarce. Powinieneś zobaczyć następujący komunikat: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Skopiuj token swojego urządzenia. Będziesz go potrzebować na następnym etapie ćwiczeń z kodowania.

Wyślij powiadomienie na swoje urządzenie

Teraz, gdy masz już token urządzenia, możesz wysłać powiadomienie.

  1. Otwórz kartę Wiadomości w chmurze w konsoli Firebase .
  2. Kliknij „Nowe powiadomienie”
  3. Wprowadź tytuł powiadomienia i tekst powiadomienia.
  4. Po prawej stronie ekranu kliknij „wyślij wiadomość testową”
  5. Wprowadź token urządzenia skopiowany z konsoli JavaScript swojej przeglądarki, a następnie kliknij znak plusa („+”)
  6. Kliknij „przetestuj”

Jeśli Twoja aplikacja znajduje się na pierwszym planie, zobaczysz powiadomienie w konsoli JavaScript.

Jeśli Twoja aplikacja działa w tle, w przeglądarce powinno pojawić się powiadomienie, jak w tym przykładzie:

de79e8638a45864c.png

13. Zasady bezpieczeństwa Cloud Firestore

Zobacz reguły bezpieczeństwa bazy danych

Cloud Firestore używa określonego języka reguł do definiowania praw dostępu, bezpieczeństwa i sprawdzania poprawności danych.

Podczas konfigurowania projektu Firebase na początku tego ćwiczenia z programowania zdecydowałeś się użyć domyślnych reguł bezpieczeństwa „trybu testowego”, aby nie ograniczać dostępu do magazynu danych. W konsoli Firebase na karcie Reguły w sekcji Baza danych możesz przeglądać i modyfikować te reguły.

W tej chwili powinieneś zobaczyć domyślne reguły, które nie ograniczają dostępu do magazynu danych. Oznacza to, że każdy użytkownik może czytać i zapisywać dowolne kolekcje w Twoim magazynie danych.

rules_version = '2';

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

Zaktualizujesz reguły, aby ograniczyć pewne rzeczy, korzystając z następujących reguł:

zasady Firestore

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;
    }
  }
}

Reguły bezpieczeństwa powinny zostać automatycznie zaktualizowane w pakiecie emulatorów.

Zobacz zasady bezpieczeństwa Cloud Storage

Cloud Storage for Firebase używa określonego języka reguł do definiowania praw dostępu, zabezpieczeń i sprawdzania poprawności danych.

Podczas konfigurowania projektu Firebase na początku tego ćwiczenia z programowania zdecydowałeś się użyć domyślnej reguły bezpieczeństwa Cloud Storage, która pozwala tylko uwierzytelnionym użytkownikom korzystać z Cloud Storage. W konsoli Firebase na karcie Reguły w sekcji Przechowywanie możesz przeglądać i modyfikować reguły. Powinieneś zobaczyć domyślną regułę, która pozwala każdemu zalogowanemu użytkownikowi czytać i zapisywać dowolne pliki w Twoim zasobniku pamięci.

rules_version = '2';

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

Zaktualizujesz reguły, aby wykonać następujące czynności:

  • Zezwalaj każdemu użytkownikowi na zapis tylko do własnych, określonych folderów
  • Zezwalaj każdemu na czytanie z Cloud Storage
  • Upewnij się, że przesłane pliki to obrazy
  • Ogranicz rozmiar obrazów, które można przesłać, do maksymalnie 5 MB

Można to wdrożyć, stosując następujące zasady:

zasady przechowywania

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. Wdróż swoją aplikację za pomocą Hostingu Firebase

Firebase oferuje usługę hostingową do obsługi Twoich zasobów i aplikacji internetowych. Możesz wdrożyć swoje pliki w Hostingu Firebase za pomocą interfejsu wiersza polecenia Firebase. Przed wdrożeniem musisz określić w pliku firebase.json , które pliki lokalne powinny zostać wdrożone. W przypadku tych zajęć z programowania już to zrobiłeś, ponieważ ten krok był wymagany, aby udostępnić nasze pliki podczas tych zajęć z programowania. Ustawienia hostingu są określone w atrybucie 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"
  }
}

Te ustawienia informują interfejs CLI, że chcesz wdrożyć wszystkie pliki w katalogu ./public ( "public": "./public" ).

  1. Upewnij się, że wiersz poleceń uzyskuje dostęp do lokalnego katalogu angularfire-start Twojej aplikacji.
  2. Wdróż swoje pliki w projekcie Firebase, uruchamiając następujące polecenie:
ng deploy

Następnie wybierz opcję Firebase i postępuj zgodnie z instrukcjami wyświetlanymi w wierszu poleceń.

  1. Konsola powinna wyświetlić następujące informacje:
=== 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. Odwiedź swoją aplikację internetową, która jest teraz w pełni hostowana w globalnej sieci CDN, korzystając z Firebase Hosting w dwóch Twoich własnych subdomenach Firebase:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Alternatywnie możesz uruchomić firebase open hosting:site w wierszu poleceń.

Odwiedź dokumentację, aby dowiedzieć się więcej o działaniu Firebase Hosting .

Przejdź do sekcji Hosting konsoli Firebase w swoim projekcie, aby wyświetlić przydatne informacje i narzędzia dotyczące hostingu, w tym historię wdrożeń, funkcje przywracania poprzednich wersji aplikacji oraz przepływ pracy związany z konfiguracją domeny niestandardowej.

15. Gratulacje!

Użyłeś Firebase do zbudowania aplikacji internetowej do czatowania w czasie rzeczywistym!

Co opisałeś

  • Uwierzytelnianie Firebase
  • Chmura Firestore
  • Pakiet SDK Firebase do przechowywania w chmurze
  • Wiadomości w chmurze Firebase
  • Monitorowanie wydajności Firebase
  • Hosting Firebase

Następne kroki

Ucz się więcej

16. [Opcjonalnie] Wymuś kontrolę aplikacji

Firebase App Check pomaga zabezpieczyć Twoje usługi przed niepożądanym ruchem i pomaga chronić backend przed nadużyciami. W tym kroku dodasz weryfikację danych uwierzytelniających i zablokujesz nieautoryzowanych klientów za pomocą funkcji App Check i reCAPTCHA Enterprise .

Najpierw musisz włączyć Sprawdzanie aplikacji i reCaptcha.

Włączanie reCaptcha Enterprise

  1. W konsoli Cloud znajdź i wybierz reCaptcha Enterprise w obszarze Bezpieczeństwo.
  2. Włącz usługę zgodnie z monitem i kliknij opcję Utwórz klucz .
  3. Wprowadź nazwę wyświetlaną zgodnie z monitem i wybierz opcję Witryna jako typ platformy.
  4. Dodaj wdrożone adresy URL do listy domen i upewnij się, że opcja „Użyj testu pola wyboru” nie jest zaznaczona .
  5. Kliknij opcję Utwórz klucz i przechowuj wygenerowany klucz w bezpiecznym miejscu. Będziesz go potrzebować w dalszej części tego kroku.

Włączanie sprawdzania aplikacji

  1. W konsoli Firebase znajdź sekcję Kompilacja w lewym panelu.
  2. Kliknij opcję Kontrola aplikacji , a następnie kliknij kartę Metoda logowania , aby przejść do opcji Kontrola aplikacji .
  3. Kliknij opcję Zarejestruj i po wyświetleniu monitu wprowadź klucz reCaptcha Enterprise, a następnie kliknij przycisk Zapisz .
  4. W widoku interfejsów API wybierz opcję Pamięć i kliknij opcję Wymuszaj . Zrób to samo dla Cloud Firestore .

Kontrola aplikacji powinna zostać teraz wymuszona! Odśwież aplikację i spróbuj wyświetlić lub wysłać wiadomości na czacie. Powinieneś otrzymać komunikat o błędzie:

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

Oznacza to, że Sprawdzanie aplikacji domyślnie blokuje niezweryfikowane żądania. Teraz dodajmy weryfikację do Twojej aplikacji.

Przejdź do pliku environment.ts i dodaj reCAPTCHAEnterpriseKey do obiektu 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"
  },
};

Zastąp wartość key swoim tokenem reCaptcha Enterprise.

Następnie przejdź do pliku app.module.ts i dodaj następujące importy:

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

W tym samym pliku app.module.ts dodaj następującą deklarację zmiennej globalnej:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

W przypadku importu dodaj inicjalizację App Check za pomocą ReCaptchaEnterpriseProvider i ustaw isTokenAutoRefreshEnabled na true , aby umożliwić automatyczne odświeżanie tokenów.

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;
}),

Aby umożliwić testowanie lokalne, ustaw wartość self.FIREBASE_APPCHECK_DEBUG_TOKEN na true . Kiedy odświeżysz aplikację w localhost , spowoduje to zarejestrowanie tokenu debugowania w konsoli podobny do:

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.

Teraz przejdź do widoku aplikacji sprawdzania aplikacji w konsoli Firebase.

Kliknij rozszerzone menu i wybierz opcję Zarządzaj tokenami debugowania .

Następnie kliknij Dodaj token debugowania i wklej token debugowania z konsoli zgodnie z monitem.

Przejdź do pliku chat.service.ts i dodaj następujący import:

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

W tym samym pliku chat.service.ts wstrzyknij App Check wraz z innymi usługami Firebase.

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

Gratulacje! Sprawdzanie aplikacji powinno teraz działać w Twojej aplikacji.