Sposoby oszczędzania danych |
|
---|---|
PUT | zapisywać lub zastępować dane w określonej ścieżce, np. fireblog/users/user1/<data> |
PATCH | zaktualizować niektóre klucze na zdefiniowanej ścieżce bez zastępowania wszystkich danych; |
POST | Dodaj do listy danych w naszej bazie danych Firebase. Za każdym razem, gdy wysyłamy żądanie POST , klient Firebase generuje unikalny klucz, np. fireblog/users/<unique-id>/<data> |
USUŃ | Usuń dane z określonej bazy danych Firebase. |
Zapisywanie danych za pomocą metody PUT
Podstawową operacją zapisu w interfejsie API REST jest PUT
. Aby zademonstrować zapisywanie danych, utworzymy aplikację do blogowania z wpisami i użytkownikami. Wszystkie dane naszej aplikacji będą przechowywane w ścieżce „fireblog” pod adresem URL bazy danych Firebase „https://docs-examples.firebaseio.com/fireblog”.
Zacznijmy od zapisania niektórych danych użytkownika do bazy danych Firebase. Każdego użytkownika będziemy przechowywać pod unikalną nazwą użytkownika, a także jego imię i nazwisko oraz datę urodzenia. Ponieważ każdy użytkownik ma niepowtarzalną nazwę użytkownika, warto użyć tutaj parametru PUT
zamiast POST
, ponieważ klucz już mamy i nie trzeba go tworzyć.
Za pomocą funkcji PUT
możemy zapisywać w naszej bazie danych Firebase ciągi tekstowe, liczby, wartości logiczne, tablice i dowolne obiekty JSON. W tym przypadku przekazujemy obiekt:
curl -X PUT -d '{ "alanisawesome": { "name": "Alan Turing", "birthday": "June 23, 1912" } }' 'https://docs-examples.firebaseio.com/fireblog/users.json'
Gdy obiekt JSON jest zapisywany w bazie danych, jego właściwości są automatycznie mapowane na pozycje podrzędne w postaci zagnieżdżonej. Jeśli przejdziesz do nowo utworzonego węzła, zobaczysz wartość „Alan Turing”. Możemy też zapisywać dane bezpośrednio w lokalizacji podrzędnej:
curl -X PUT -d '"Alan Turing"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'
Opisane powyżej 2 przykłady – zapisywanie wartości w tym samym czasie co obiekt i oddzielnie w miejscach podrzędnych – spowodują zapisanie tych samych danych w bazie danych Firebase:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing" } } }
Pomyślne żądanie będzie oznaczone kodem stanu HTTP 200 OK
, a odpowiedź będzie zawierać dane zapisane w bazie danych. Pierwszy przykład wywoła tylko jedno zdarzenie na klientach, którzy obserwują dane, a drugi – dwa. Pamiętaj, że jeśli dane są już dostępne na ścieżce użytkowników, pierwsze podejście nadpisze je, ale drugie zmodyfikuje tylko wartość każdego osobnego węzła podrzędnego, pozostawiając inne bez zmian. Zmienna PUT
jest odpowiednikiem zmiennej set()
w pakiecie JavaScript SDK.
Aktualizowanie danych za pomocą PATCH
Dzięki żądaniu PATCH
możemy zaktualizować informacje o konkretnych dzieciach w danej lokalizacji bez nadpisywania dotychczasowych danych. Dodajmy do danych użytkownika pseudonim Turinga za pomocą żądania PATCH
:
curl -X PATCH -d '{ "nickname": "Alan The Machine" }' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
Powyższe żądanie spowoduje zapisanie wartości nickname
w obiekcie alanisawesome
bez usuwania elementów podrzędnych name
ani birthday
. Jeśli zamiast tego wysłalibyśmy prośbę PUT
, treści name
i birthday
zostałyby usunięte, ponieważ nie zostały uwzględnione w prośbie. Dane w naszej bazie danych Firebase wyglądają teraz tak:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing", "nickname": "Alan The Machine" } } }
Pomyślne żądanie będzie oznaczone kodem stanu HTTP 200 OK
, a odpowiedź będzie zawierać zaktualizowane dane zapisane w bazie danych.
Firebase obsługuje też aktualizacje wielościeżkowe. Oznacza to, że PATCH
może teraz aktualizować wartości w różnych miejscach w bazie danych Firebase jednocześnie. Ta potężna funkcja ułatwia denormalizację danych. Dzięki aktualizacjom wielościeżkowym możemy dodać przezwiska do Alana i Grace jednocześnie:
curl -X PATCH -d '{ "alanisawesome/nickname": "Alan The Machine", "gracehopper/nickname": "Amazing Grace" }' \ 'https://docs-examples.firebaseio.com/fireblog/users.json'
Po tej aktualizacji dodano do niego pseudonimy Alana i Grace:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing", "nickname": "Alan The Machine" }, "gracehop": { "date_of_birth": "December 9, 1906", "full_name": "Grace Hopper", "nickname": "Amazing Grace" } } }
Pamiętaj, że próba zaktualizowania obiektów przez zapisanie obiektów z dołączonymi ścieżkami spowoduje inne działanie. Zobaczmy, co się stanie, jeśli zamiast tego spróbujemy zaktualizować Grace i Alana w ten sposób:
curl -X PATCH -d '{ "alanisawesome": {"nickname": "Alan The Machine"}, "gracehopper": {"nickname": "Amazing Grace"} }' \ 'https://docs-examples.firebaseio.com/fireblog/users.json'
Spowoduje to inne działanie, a mianowicie zastąpienie całego węzła /fireblog/users
:
{ "users": { "alanisawesome": { "nickname": "Alan The Machine" }, "gracehop": { "nickname": "Amazing Grace" } } }
Aktualizowanie danych za pomocą żądań warunkowych
Aby zaktualizować dane zgodnie z ich obecnym stanem, możesz użyć żądań warunkowych, które są odpowiednikiem REST dla transakcji. Jeśli na przykład chcesz zwiększyć liczbę głosów za i upewnić się, że odzwierciedla ona prawidłowo liczbę głosów za jednocześnie, użyj warunkowego żądania, aby zapisać nową wartość w liczniku. Zamiast 2 zapisań, które zmieniają licznik na tę samą wartość, jeden z tych zapisów zakończy się niepowodzeniem, a potem możesz ponownie przesłać żądanie z nową wartością.- Aby wykonać żądanie warunkowe w danej lokalizacji, pobierz unikalny identyfikator bieżących danych w tej lokalizacji lub tag E. Jeśli dane w tej lokalizacji ulegną zmianie, zmieni się też ETag. Możesz poprosić o E-Tag za pomocą dowolnej metody innej niż
PATCH
. W tym przykładzie użyto żądaniaGET
. Wywołanie ETag w nagłówku zwraca ETag określonego w odpowiedzi HTTP miejsca.curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
HTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 10 // Current value of the data at the specified location
- W następnym żądaniu
PUT
lubDELETE
uwzględnij zwrócony tag ETag, aby zaktualizować dane, które pasują do tej wartości. W naszym przykładzie, aby zaktualizować licznik do 11 lub o 1 większy od początkowej wartości pobranej 10, a także odrzucić żądanie, jeśli wartość nie pasuje, użyj tego kodu: Jeśli wartość danych w wybranej lokalizacji nadal wynosi 10, tag ETag w żądaniucurl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
PUT
pasuje do siebie, a żądanie się powiedzie, zapisując 11 do bazy danych. Jeśli lokalizacja nie pasuje już do ETaga, co może się zdarzyć, gdy inny użytkownik zapisze nową wartość w bazie danych, żądanie nie powiedzie się, a dane nie zostaną zapisane w lokalizacji. Odpowiedź zawiera nową wartość i ETag.HTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * Cache-Control: no-cache 11 // New value of the data at the specified location, written by the conditional request
HTTP/1.1 412 Precondition Failed Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 12 // New value of the data at the specified location
- Jeśli zdecydujesz się ponownie przesłać prośbę, użyj nowych informacji. Realtime Databasenie próbuje automatycznie ponownie wysyłać żądań warunkowych, które zakończyły się niepowodzeniem. Możesz jednak użyć nowej wartości i ETag, aby utworzyć nowe żądanie warunkowe z informacjami zwróconymi przez odpowiedź na błąd.
Żądania warunkowe oparte na protokole REST implementują standard HTTP if-match. Różnią się jednak od standardowych w tych kwestiach:
- W przypadku każdego żądania if-match możesz podać tylko 1 wartość ETag, a nie kilka.
- Chociaż standard zaleca zwracanie tagów ETag ze wszystkimi żądaniami, Realtime Database zwraca je tylko w przypadku żądań z nagłówkiem
X-Firebase-ETag
. Pozwala to obniżyć koszty rozliczeń za żądania standardowe.
Żądania warunkowe mogą też być wolniejsze niż typowe żądania REST.
Zapisywanie list danych
Aby wygenerować unikalny klucz oparty na sygnaturze czasową dla każdego elementu podrzędnego dodanego do odwołania do bazy danych Firebase, możemy wysłać żądanie POST
. W przypadku ścieżki users
sensowne było zdefiniowanie własnych kluczy, ponieważ każdy użytkownik ma unikalną nazwę użytkownika. Gdy jednak użytkownicy dodadzą do aplikacji posty z bloga, użyjemy żądania POST
, aby automatycznie wygenerować klucz dla każdego z nich:
curl -X POST -d '{ "author": "alanisawesome", "title": "The Turing Machine" }' 'https://docs-examples.firebaseio.com/fireblog/posts.json'
Ścieżka posts
zawiera teraz te dane:
{ "posts": { "-JSOpn9ZC54A4P4RoqVa": { "author": "alanisawesome", "title": "The Turing Machine" } } }
Zwróć uwagę, że klucz -JSOpn9ZC54A4P4RoqVa
został wygenerowany automatycznie, ponieważ użyliśmy żądania POST
. Żądanie zakończone powodzeniem zostanie oznaczone kodem stanu HTTP 200 OK
, a odpowiedź będzie zawierać klucz nowych dodanych danych:
{"name":"-JSOpn9ZC54A4P4RoqVa"}
Usuwanie danych
Aby usunąć dane z bazy danych, możemy wysłać żądanie DELETE
z adresem URL ścieżki, z której chcemy usunąć dane. Zmiana ta spowoduje usunięcie Alana z ścieżkiusers
:
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
Pomyślne żądanie DELETE
będzie sygnalizowane przez kod stanu HTTP 200 OK
z odpowiedzią zawierającą dane JSON null
.
Parametry identyfikatora URI
Podczas zapisywania danych do bazy danych interfejs REST API akceptuje te parametry URI:
uwierzytelnienie
Parametr żądania auth
umożliwia dostęp do danych chronionych przez Firebase Realtime Database Security Rules i jest obsługiwany przez wszystkie typy żądań. Argument może być tajnym kluczem aplikacji Firebase lub tokenem uwierzytelniania, o którym piszemy w sekcji autoryzacja użytkownika. W tym przykładzie wysyłamy żądanie POST
z parametrem auth
, gdzie CREDENTIAL
to nasz obiekt tajny aplikacji Firebase lub token uwierzytelniający:
curl -X POST -d '{"Authenticated POST request"}' \ 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
drukuj
Parametr print
umożliwia określenie formatu odpowiedzi z bazy danych. Dodanie parametru print=pretty
do żądania spowoduje, że dane zostaną zwrócone w formacie zrozumiałym dla człowieka. print=pretty
jest obsługiwana przez żądania GET
, PUT
, POST
, PATCH
i DELETE
.
Aby podczas zapisywania danych nie wyświetlać danych wyjściowych z serwera, możemy dodać do naszej prośby parametrprint=silent
. Jeśli żądanie zostanie zrealizowane, odpowiedź będzie pusta i będzie oznaczona kodem stanu HTTP 204 No Content
.
print=silent
jest obsługiwana przez żądania GET
, PUT
, POST
i PATCH
.
Zapisywanie wartości serwera
Wartości serwera można zapisywać w lokalizacji za pomocą wartości zastępczej, która jest obiektem z jednym kluczem ".sv"
. Wartość tego klucza to typ wartości serwera, który chcemy ustawić.
Aby np. ustawić sygnaturę czasową podczas tworzenia użytkownika, możesz wykonać te czynności:
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
to jedyna obsługiwana wartość serwera. Jest to czas w milisekundach od epoki UNIX.
Poprawianie wydajności zapisu
Jeśli do bazy danych zapisujemy duże ilości danych, możemy użyć parametru
print=silent
, aby zwiększyć wydajność zapisu i zmniejszyć wykorzystanie przepustowości. W przypadku zwykłego zapisu serwer odpowiada danymi JSON, które zostały zapisane.
Gdy określona jest wartość print=silent
, serwer natychmiast zamyka połączenie po otrzymaniu danych, co zmniejsza wykorzystanie przepustowości.
W przypadku wysyłania wielu żądań do bazy danych możemy ponownie użyć połączenia HTTPS, wysyłając żądanie Keep-Alive
w nagłówku HTTP.
Warunki błędu
Interfejs REST API zwraca kody błędów w tych okolicznościach:
Kody stanu HTTP | |
---|---|
400 Nieprawidłowe żądanie |
Jeden z tych błędów:
|
401 Brak autoryzacji |
Jeden z tych błędów:
|
404 Nie znaleziono | Nie udało się znaleźć wskazanej bazy danych Firebase. |
500 Wewnętrzny błąd serwera | Serwer zwrócił błąd. Więcej informacji znajdziesz w komunikacie o błędzie. |
503 Usługa niedostępna | Wskazana Baza danych czasu rzeczywistego Firebase jest tymczasowo niedostępna, co oznacza, że żądanie nie zostało wysłane. |
Zabezpieczanie danych
Firebase ma język bezpieczeństwa, który pozwala nam określać, którzy użytkownicy mają dostęp do odczytu i zapisu do różnych węzłów danych. Więcej informacji znajdziesz w artykule Realtime Database Security Rules.
W następnej sekcji dowiesz się, jak pobierać dane z bazy danych Firebase za pomocą interfejsu REST API.