Jak zbudować własny system komentarzy za pomocą Firebase

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Czy kiedykolwiek chciałeś mieć sekcję komentarzy na swoim blogu, ale przytłaczały Cię wysokie koszty i rozwiązania konserwacyjne? Firebase może być Twoim wybawcą. Z tego przewodnika dowiemy się, jak dodać sekcję komentarzy do swojego bloga za pomocą Firebase, jednocześnie poznając podstawy Firebase.

Sekcja komentarzy to świetny sposób na zbudowanie społeczności dla swojego bloga. Ostatnio, gdy zacząłem blogować, pomyślałem o dodaniu sekcji komentarzy. Nie było to jednak łatwe. Hostowane systemy komentarzy, takie jak Disqus i Commento, mają własny zestaw problemów:

  • Są właścicielami Twoich danych.
  • Nie są wolne.
  • Nie możesz ich zbytnio dostosować.

Postanowiłem więc zbudować własny system komentarzy. Firebase wydawał się idealną alternatywą hostingową dla serwera zaplecza.

Przede wszystkim czerpiesz wszystkie korzyści z posiadania własnej bazy danych: kontrolujesz dane i możesz je dowolnie ustrukturyzować. Po drugie, nie musisz konfigurować serwera zaplecza. Możesz go łatwo kontrolować z przodu. To tak, jakby mieć to, co najlepsze z obu światów: hostowany system bez kłopotliwego zaplecza.

W tym poście właśnie to zrobimy. Dowiemy się, jak skonfigurować Firebase z Gatsby, statycznym generatorem witryn. Ale zasady można zastosować do dowolnego generatora stron statycznych.

Zanurzmy się!

Co to jest Firebase?

Firebase to zaplecze jako usługa oferująca narzędzia dla programistów aplikacji, takie jak baza danych, hosting, funkcje chmury, uwierzytelnianie, analityka i pamięć masowa.

Cloud Firestore (baza danych Firebase) to funkcjonalność, której będziemy używać w tym projekcie. Jest to baza danych NoSQL. Oznacza to, że nie ma struktury jak baza danych SQL z wierszami, kolumnami i tabelami. Możesz myśleć o tym jako o dużym drzewie JSON.

Wprowadzenie do projektu

Zainicjujmy projekt, klonując lub pobierając repozytorium z GitHub.

Stworzyłem dwie gałęzie dla każdego kroku (jedną na początku i jedną na końcu), aby ułatwić Ci śledzenie zmian na bieżąco.

Uruchommy projekt za pomocą następującego polecenia:

 gatsby develop

Jeśli otworzysz projekt w przeglądarce, zobaczysz nagie szkielety podstawowego bloga.

Podstawowy blog
(duży podgląd)

Sekcja komentarzy nie działa. Po prostu ładuje przykładowy komentarz, a po przesłaniu komentarza rejestruje szczegóły w konsoli.

Naszym głównym zadaniem jest uruchomienie sekcji komentarzy.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Jak działa sekcja komentarzy

Zanim cokolwiek zrobisz, zrozummy, jak działa kod sekcji komentarzy.

Cztery komponenty obsługują sekcje komentarzy:

  • blog-post.js
  • Comments.js
  • CommentForm.js
  • Comment.js

Najpierw musimy zidentyfikować komentarze do posta. Można to zrobić, tworząc unikalny identyfikator dla każdego posta na blogu lub możemy użyć ślimaka, który jest zawsze unikalny.

Plik blog-post.js jest składnikiem układu dla wszystkich postów na blogu. Jest to idealny punkt wyjścia do uzyskania informacji o wpisie na blogu. Odbywa się to za pomocą zapytania GraphQL.

 export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `

Przed wysłaniem go do komponentu Comments.js użyjmy metody substring() , aby pozbyć się końcowego ukośnika ( / ), który Gatsby dodaje do ślimaka.

 const slug = post.fields.slug.substring(1, post.fields.slug.length - 1) return ( <Layout> <div className="container"> <h1>{post.frontmatter.title}</h1> <div dangerouslySetInnerHTML={{ __html: post.html }} /> <Comments comments={comments} slug={slug} /> </div> </Layout> ) }

Komponent Comments.js mapuje każdy komentarz i przekazuje jego dane do Comment.js wraz z wszelkimi odpowiedziami. W przypadku tego projektu zdecydowałem się zejść o jeden poziom w głąb systemu komentowania.

Komponent ładuje również CommentForm.js , aby przechwycić wszelkie komentarze najwyższego poziomu.

 const Comments = ({ comments, slug }) => { return ( <div> <h2>Join the discussion</h2> <CommentForm slug={slug} /> <CommentList> {comments.length > 0 && comments .filter(comment => !comment.pId) .map(comment => { let child if (comment.id) { child = comments.find(c => comment.id === c.pId) } return ( <Comment key={comment.id} child={child} comment={comment} slug={slug} /> ) })} </CommentList> </div> ) }

Przejdźmy do CommentForm.js . Ten plik jest prosty, renderuje formularz komentarza i obsługuje jego przesłanie. Metoda przesyłania po prostu rejestruje szczegóły w konsoli.

 const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }

W pliku Comment.js dużo się dzieje. Podzielmy to na mniejsze kawałki.

Po pierwsze, istnieje składnik SingleComment , który renderuje komentarz.

Używam Adorable API, aby uzyskać fajny awatar. Biblioteka Moment.js służy do renderowania czasu w formacie czytelnym dla człowieka.

 const SingleComment = ({ comment }) => ( <div> <div className="flex-container"> <div className="flex"> <img src="https://api.adorable.io/avazars/65/[email protected]" alt="Avatar" /> </div> <div className="flex"> <p className="comment-author"> {comment.name} <span>says</span> </p> {comment.time} &&(<time>(moment(comment.time.toDate()).calendar()}</time>)} </div> </div> </p>{comment.content}</p> </div> )

Dalej w pliku znajduje się komponent Comment . Ten składnik pokazuje komentarz podrzędny, jeśli został do niego przekazany komentarz podrzędny. W przeciwnym razie renderuje pole odpowiedzi, które można włączać i wyłączać, klikając przycisk "Odpowiedz" lub przycisk "Anuluj odpowiedź".

 const Comment = ({ comment, child, slug }) => { const [showReplyBox, setShowReplyBox] = useState(false) return ( <CommentBox> <SingleComment comment={comment} /> {child && ( <CommentBox child className=comment-reply"> <SingleComment comment={child} /> </CommentBox> )} {!child && ( <div> {showReplyBox ? ( <div> <button className="btn bare" onClick={() => setShowReplyBoy(false)} > Cancel Reply </button> <CommentForm parentId={comment.id} slug={slug} /> </div> ) : ( <button className="btn bare" onClick={() => setShowReplyBox(true)}> Reply </button> )} </div> )} </div> )} </CommentBox>

Teraz, gdy mamy przegląd, przejdźmy przez kroki tworzenia naszej sekcji komentarzy.

1. Dodaj Firebase

Najpierw skonfigurujmy Firebase dla naszego projektu.

Zacznij od rejestracji. Przejdź do Firebase i załóż konto Google. Jeśli go nie masz, kliknij „Rozpocznij”.

Kliknij „Dodaj projekt”, aby dodać nowy projekt. Dodaj nazwę swojego projektu i kliknij „Utwórz projekt”.

Zainicjuj Firebase
(duży podgląd)

Po utworzeniu projektu musimy skonfigurować Cloud Firestore.

W menu po lewej stronie kliknij „Baza danych”. Gdy otworzy się strona z napisem „Cloud Firestore”, kliknij „Utwórz bazę danych”, aby utworzyć nową bazę danych Cloud Firestore.

Cloud Firestore
(duży podgląd)

Gdy pojawi się wyskakujące okienko, wybierz „Uruchom w trybie testowym”. Następnie wybierz najbliższą lokalizację Cloud Firestore.

Tryb testowy Firestore
(duży podgląd)

Gdy zobaczysz taką stronę, oznacza to, że pomyślnie utworzyłeś bazę danych Cloud Firestore.

Pulpit nawigacyjny Firestore
(duży podgląd)

Zakończmy ustawiając logikę dla aplikacji. Wróć do aplikacji i zainstaluj Firebase:

 yarn add firebase

Dodaj nowy plik, firebase.js , w katalogu głównym. Wklej w nim tę treść:

 import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase

Musisz zastąpić yourFirebaseConfig dla swojego projektu. Aby go znaleźć, kliknij ikonę koła zębatego obok „Przegląd projektu” w aplikacji Firebase.

Ustawienia projektu
(duży podgląd)

Spowoduje to otwarcie strony ustawień. Pod nagłówkiem Twojej aplikacji kliknij ikonę internetową, która wygląda tak:

Instalacja projektu
(duży podgląd)

Otworzy się wyskakujące okienko. W polu „Pseudonim aplikacji” wpisz dowolną nazwę i kliknij „Zarejestruj aplikację”. W ten sposób otrzymasz obiekt firebaseConfig .

 <!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.google.com/docs/web/setup#available-libraries --> <script> // Your web app's Firebase configuration var firebaseConfig = { ... }; // Initialize Firebase firbase.initializeApp(firebaseConfig); </script>

Skopiuj tylko zawartość obiektu firebaseConfig i wklej ją do pliku firebase.js .

Czy można ujawnić klucz Firebase API?

TAk. Jak stwierdził inżynier Google, ujawnienie klucza API jest w porządku.

Jedynym celem klucza API jest identyfikacja Twojego projektu z bazą danych w Google. Jeśli masz ustawione silne reguły bezpieczeństwa dla Cloud Firestore, nie musisz się martwić, że ktoś uzyska Twój klucz API.

Porozmawiamy o zasadach bezpieczeństwa w ostatniej sekcji.

Na razie uruchamiamy Firestore w trybie testowym, więc nie powinieneś publicznie ujawniać klucza API.

Jak korzystać z Firestore?

Możesz przechowywać dane w jednym z dwóch typów:

  • kolekcja
    Zbiór zawiera dokumenty. Jest jak zbiór dokumentów.
  • dokument
    Dokument zawiera dane w parze pole-wartość.

Pamiętaj, że kolekcja może zawierać tylko dokumenty, a nie inne kolekcje. Ale dokument może zawierać inne kolekcje.

Oznacza to, że jeśli chcemy przechowywać kolekcję w kolekcji, przechowujemy ją w dokumencie i przechowujemy ten dokument w kolekcji, na przykład:

 {collection-1}/{document}/{collection-2}

Jak uporządkować dane?

Cloud Firestore ma charakter hierarchiczny, więc ludzie zwykle przechowują dane w następujący sposób:

 blog/{blog-post-1}/content/comments/{comment-1}

Jednak przechowywanie danych w ten sposób często stwarza problemy.

Powiedz, że chcesz otrzymać komentarz. Musisz poszukać komentarza przechowywanego głęboko w kolekcji blogów. Dzięki temu Twój kod będzie bardziej podatny na błędy. Chris Esplin zaleca, aby nigdy nie używać podzbiorów.

Polecam przechowywanie danych jako spłaszczony obiekt:

 blog-posts/{blog-post-1} comments/{comment-1}

W ten sposób możesz łatwo pobierać i wysyłać dane.

Jak uzyskać dane z Firestore?

Firebase udostępnia dwie metody pobierania danych:

  • get()
    Służy do jednorazowego pobrania treści.
  • onSnapshot()
    Ta metoda wysyła dane, a następnie kontynuuje wysyłanie aktualizacji, chyba że zrezygnujesz z subskrypcji.

Jak wysłać dane do Firestore?

Podobnie jak w przypadku pobierania danych, Firebase ma dwie metody zapisywania danych:

  • set()
    Służy do określenia identyfikatora dokumentu.
  • add()
    Służy do tworzenia dokumentów z automatycznymi identyfikatorami.

Wiem, to było dużo do zrozumienia. Ale nie martw się, wrócimy do tych koncepcji ponownie, gdy dotrzemy do projektu.

2. Utwórz przykładową datę

Następnym krokiem jest utworzenie przykładowych danych do zapytania. Zróbmy to, przechodząc do Firebase.

Przejdź do Cloud Firestore. Kliknij „Rozpocznij kolekcję”. Wpisz comments do „Identyfikatora kolekcji”, a następnie kliknij „Dalej”.

Dodaj kolekcję
(duży podgląd)

W przypadku „ID dokumentu” kliknij „Auto-ID. Wprowadź następujące dane i kliknij „Zapisz”.

Dodaj dokument
(duży podgląd)

Podczas wprowadzania danych upewnij się, że pola „Pola” i „Typy” pasują do powyższego zrzutu ekranu. Następnie kliknij „Zapisz”.

W ten sposób ręcznie dodajesz komentarz w Firestore. Proces wygląda na uciążliwy, ale nie martw się: od teraz nasza aplikacja zajmie się dodawaniem komentarzy.

W tym momencie nasza baza danych wygląda tak: comments/{comment} .

3. Pobierz dane komentarzy

Nasze przykładowe dane są gotowe do zapytania. Zacznijmy od zebrania danych do naszego bloga.

Przejdź do blog-post.js i zaimportuj Firestore z właśnie utworzonego pliku Firebase.

 import {firestore} from "../../firebase.js"

Do zapytania użyjemy useEffect z Reacta. Jeśli jeszcze tego nie zrobiłeś, zaimportuj go również.

 useEffect(() => { firestore .collection(`comments`) .onSnapshot(snapshot => { const posts = snapshot.docs .filter(doc => doc.data().slug === slug) .map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) }, [slug])

Metoda używana do pobierania danych to onSnapshot . Dzieje się tak, ponieważ chcemy również słuchać zmian stanu. Tak więc komentarze zostaną zaktualizowane bez konieczności odświeżania przeglądarki przez użytkownika.

Użyliśmy metod filter i map , aby znaleźć komentarze, których ślimak pasuje do bieżącego ślimaka.

Ostatnią rzeczą, o której musimy pomyśleć, jest sprzątanie. Ponieważ onSnapshot nadal wysyła aktualizacje, może to spowodować wyciek pamięci w naszej aplikacji. Na szczęście Firebase zapewnia zgrabną poprawkę.

 useEffect(() => { const cleanUp = firestore .doc(`comments/${slug}`) .collection("comments") .onSnapshot(snapshot => { const posts = snapshot.docs.map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) return () => cleanUp() }, [slug])

Gdy skończysz, uruchom program gatsby develop , aby zobaczyć zmiany. Możemy teraz zobaczyć naszą sekcję komentarzy, która pobiera dane z Firebase.

Pobieranie danych Firestore
(duży podgląd)

Popracujmy nad przechowywaniem komentarzy.

4. Sklep Komentarze

Aby przechowywać komentarze, przejdź do pliku CommentForm.js . Zaimportujmy również Firestore do tego pliku.

 import { firestore } from "../../firebase.js"

Aby zapisać komentarz w Firebase, użyjemy metody add() , ponieważ chcemy, aby Firestore tworzył dokumenty z auto-ID.

Zróbmy to w metodzie handleCommentSubmission .

 firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })

Najpierw otrzymujemy odwołanie do kolekcji komentarzy, a następnie dodajemy komentarz. Używamy również metody catch , aby wyłapać wszelkie błędy podczas dodawania komentarzy.

W tym momencie, jeśli otworzysz przeglądarkę, zobaczysz działającą sekcję komentarzy. Możemy dodawać nowe komentarze, a także odpowiedzi na posty. Co bardziej niesamowite, wszystko działa bez konieczności odświeżania strony.

Przechowywanie komentarza
(duży podgląd)

Możesz także sprawdzić Firestore, aby sprawdzić, czy przechowuje dane.

Przechowywane dane w Firestore
(duży podgląd)

Na koniec porozmawiajmy o jednej kluczowej rzeczy w Firebase: regułach bezpieczeństwa.

5. Zaostrz zasady bezpieczeństwa

Do tej pory korzystaliśmy z Cloud Firestore w trybie testowym. Oznacza to, że każdy, kto ma dostęp do adresu URL, może dodawać i czytać naszą bazę danych. To jest straszne.

Aby temu zaradzić, Firebase udostępnia nam zasady bezpieczeństwa. Możemy stworzyć wzorzec bazy danych i ograniczyć niektóre działania w Cloud Firestore.

Oprócz dwóch podstawowych operacji (odczytu i zapisu) Firebase oferuje bardziej szczegółowe operacje: pobieranie, wyświetlanie listy, tworzenie, aktualizowanie i usuwanie.

Operację odczytu można podzielić na:

  • get
    Zdobądź jeden dokument.
  • list
    Uzyskaj listę dokumentów lub kolekcję.

Operację zapisu można podzielić na:

  • create
    Utwórz nowy dokument.
  • update
    Zaktualizuj istniejący dokument.
  • delete
    Usuń dokument.

Aby zabezpieczyć aplikację, wróć do Cloud Firestore. W sekcji „Reguły” wpisz:

 service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }

W pierwszej linii definiujemy usługę, którą w naszym przypadku jest Firestore. Kolejne wiersze informują Firebase, że wszystko w kolekcji comments może zostać odczytane i utworzone.

Gdybyśmy tego użyli:

 allow read, write;

… oznaczałoby to, że użytkownicy mogliby aktualizować i usuwać istniejące komentarze, czego nie chcemy.

Reguły bezpieczeństwa Firebase są niezwykle potężne, co pozwala nam ograniczać określone dane, działania, a nawet użytkowników.

Sekcja tworzenia własnych komentarzy

Gratulacje! Właśnie poznałeś moc Firebase. Jest to doskonałe narzędzie do budowania bezpiecznych i szybkich aplikacji.

Zbudowaliśmy super prostą sekcję komentarzy. Ale nic Cię nie powstrzyma przed odkrywaniem dalszych możliwości:

  • Dodaj zdjęcia profilowe i przechowuj je w Cloud Storage dla Firebase;
  • Użyj Firebase, aby umożliwić użytkownikom tworzenie kont i uwierzytelnianie ich za pomocą uwierzytelniania Firebase;
  • Użyj Firebase do tworzenia wbudowanych komentarzy w stylu Medium.

Świetnym sposobem na rozpoczęcie byłoby zapoznanie się z dokumentacją Firestore.

Na koniec przejdźmy do sekcji komentarzy poniżej i omówmy swoje doświadczenia z tworzeniem sekcji komentarzy za pomocą Firebase.

The Smashing Cat odkrywa nowe spostrzeżenia, oczywiście w Smashing Workshops.

Przydatne bity front-end i UX, dostarczane raz w tygodniu.

Z narzędziami, które pomogą Ci lepiej wykonywać swoją pracę. Subskrybuj i otrzymuj listy kontrolne inteligentnego projektowania interfejsu w formacie PDF Witalija za pośrednictwem poczty e-mail.

Na froncie i UX. Zaufany przez 190 000 osób.