Zapisywanie danych

Sposoby zapisywania danych

UMIEŚCIĆ Zapisz lub zastąp dane w zdefiniowanej ścieżce , np fireblog/users/user1/<data>
SKRAWEK Zaktualizuj niektóre klucze dla zdefiniowanej ścieżki 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, na przykład fireblog/users/<unique-id>/<data>
USUWAĆ Usuń dane z określonego odwołania do bazy danych Firebase.

Zapisywanie danych za pomocą PUT

Podstawową operacją zapisu przez REST API jest PUT . Aby zademonstrować zapisywanie danych, zbudujemy aplikację do blogowania z wpisami i użytkownikami. Wszystkie dane dla naszej aplikacji będą przechowywane pod ścieżką `fireblog`, pod adresem URL bazy danych Firebase `https://docs-examples.firebaseio.com/fireblog`.

Zacznijmy od zapisania niektórych danych użytkownika w naszej bazie danych Firebase. Będziemy przechowywać każdego użytkownika według unikalnej nazwy użytkownika, a także będziemy przechowywać jego imię i nazwisko oraz datę urodzenia. Ponieważ każdy użytkownik będzie miał unikalną nazwę użytkownika, sensowne jest użycie tutaj PUT zamiast POST , ponieważ mamy już klucz i nie musimy go tworzyć.

Za pomocą PUT możemy zapisać ciąg znaków, liczbę, wartość logiczną, tablicę lub dowolny obiekt JSON do naszej bazy danych Firebase. W tym przypadku przekażemy mu 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, właściwości obiektu są automatycznie mapowane na lokalizacje podrzędne w sposób zagnieżdżony. Jeśli przejdziemy do nowo utworzonego węzła, zobaczymy wartość „Alan Turing”. Możemy również 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'

Powyższe dwa przykłady — zapisanie wartości w tym samym czasie co obiekt i zapisanie ich oddzielnie w lokalizacjach podrzędnych — spowodują zapisanie tych samych danych w naszej bazie danych Firebase:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

Pomyślne żądanie zostanie potwierdzone kodem stanu HTTP 200 OK , a odpowiedź będzie zawierała dane, które zapisaliśmy w bazie danych. Pierwszy przykład wyzwoli tylko jedno zdarzenie na klientach, którzy oglądają dane, podczas gdy drugi przykład wyzwoli dwa. Należy zauważyć, że gdyby dane już istniały w ścieżce użytkownika, pierwsze podejście nadpisałoby je, ale druga metoda zmodyfikowałaby tylko wartość każdego oddzielnego węzła podrzędnego, pozostawiając inne elementy podrzędne bez zmian. PUT jest odpowiednikiem set() w naszym JavaScript SDK.

Aktualizowanie danych za pomocą PATCH

Korzystając z żądania PATCH , możemy zaktualizować określone elementy podrzędne w lokalizacji bez nadpisywania istniejących danych. Dodajmy pseudonim Turinga do jego danych użytkownika 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 wpisanie nickname do naszego alanisawesome obiektu bez usuwania name lub birthday dzieci. Zwróć uwagę, że gdybyśmy zamiast tego wysłali tutaj żądanie PUT , name i nazwisko oraz birthday zostałyby usunięte, ponieważ nie zostały uwzględnione w żądaniu. 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 zostanie wskazane przez kod stanu HTTP 200 OK , a odpowiedź będzie zawierać zaktualizowane dane zapisane w bazie danych.

Firebase obsługuje również aktualizacje wielościeżkowe. Oznacza to, że PATCH może teraz aktualizować wartości w wielu lokalizacjach w bazie danych Firebase w tym samym czasie, co jest potężną funkcją, która pomaga w denormalizacji danych . Korzystając z aktualizacji wielościeżkowych, możemy jednocześnie dodawać pseudonimy zarówno Alanowi, jak i Grace:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Po tej aktualizacji zarówno Alan, jak i Grace mają dodane pseudonimy:

{
  "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"
    }
  }
}

Należy zauważyć, że próba aktualizacji obiektów przez zapisanie obiektów z dołączonymi ścieżkami spowoduje inne zachowanie. Przyjrzyjmy się, 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'

Powoduje to inne zachowanie, a mianowicie nadpisanie całego węzła /fireblog/users :

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

Aktualizowanie danych za pomocą żądań warunkowych

Możesz użyć żądań warunkowych, odpowiedników transakcji REST, aby zaktualizować dane zgodnie z ich istniejącym stanem. Na przykład, jeśli chcesz zwiększyć licznik głosów pozytywnych i upewnić się, że liczba dokładnie odzwierciedla wiele równoczesnych głosów pozytywnych, użyj żądania warunkowego, aby zapisać nową wartość w liczniku. Zamiast dwóch zapisów, które zmieniają licznik na tę samą liczbę, jedno z żądań zapisu kończy się niepowodzeniem i można ponowić żądanie z nową wartością.
  1. Aby wykonać żądanie warunkowe w lokalizacji, uzyskaj unikalny identyfikator bieżących danych w tej lokalizacji lub ETag. Jeśli dane zmienią się w tej lokalizacji, zmieni się również ETag. Możesz zażądać ETag przy użyciu dowolnej metody innej niż PATCH . Poniższy przykład używa żądania GET .
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    Konkretne wywołanie ETag w nagłówku zwraca ETag określonej lokalizacji w odpowiedzi HTTP.
    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
    
  2. Uwzględnij zwrócony ETag w następnym żądaniu PUT lub DELETE , aby zaktualizować dane, które konkretnie pasują do tej wartości ETag. Zgodnie z naszym przykładem, aby zaktualizować licznik do wartości 11 lub 1 większej niż pobrana początkowa wartość 10 i odrzucić żądanie, jeśli wartość już się nie zgadza, użyj następującego kodu:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    Jeśli wartość danych w określonym location nadal wynosi 10, ETag w żądaniu PUT jest zgodny, a żądanie się powiedzie, zapisując 11 do bazy danych.
    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
    
    Jeśli lokalizacja nie jest już zgodna z ETag, co może się zdarzyć, jeśli inny użytkownik zapisze nową wartość w bazie danych, żądanie kończy się niepowodzeniem bez zapisu w lokalizacji. Odpowiedź zwrotna zawiera nową wartość i ETag.
    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
    
  3. Użyj nowych informacji, jeśli zdecydujesz się ponowić żądanie. Baza danych czasu rzeczywistego nie ponawia automatycznie żądań warunkowych, które zakończyły się niepowodzeniem. Możesz jednak użyć nowej wartości i ETag do zbudowania nowego żądania warunkowego z informacjami zwróconymi przez odpowiedź niepowodzenia.

Żądania warunkowe oparte na REST implementują standard HTTP if-match . Różnią się one jednak od standardu w następujący sposób:

  • Możesz podać tylko jedną wartość ETag dla każdego żądania if-match, a nie wiele.
  • Podczas gdy standard sugeruje, że tagi ETagi są zwracane ze wszystkimi żądaniami, baza danych czasu rzeczywistego zwraca tagi ETag tylko z żądaniami zawierającymi nagłówek X-Firebase-ETag . Zmniejsza to koszty rozliczeń w przypadku standardowych żądań.

Żądania warunkowe mogą być również wolniejsze niż typowe żądania REST.

Zapisywanie list danych

Aby wygenerować unikalny klucz oparty na sygnaturze czasowej dla każdego dziecka dodanego do odwołania do bazy danych Firebase, możemy wysłać żądanie POST . Dla naszej ścieżki users sensowne było zdefiniowanie własnych kluczy, ponieważ każdy użytkownik ma unikalną nazwę użytkownika. Ale gdy użytkownicy dodają posty na blogu do aplikacji, użyjemy żądania POST , aby automatycznie wygenerować klucz dla każdego posta na blogu:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

Nasza ścieżka posts zawiera teraz następujące dane:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

Zauważ, że klucz -JSOpn9ZC54A4P4RoqVa został dla nas wygenerowany automatycznie, ponieważ użyliśmy żądania POST . Pomyślne żądanie zostanie oznaczone kodem stanu HTTP 200 OK , a odpowiedź będzie zawierać klucz nowych danych, które zostały dodane:

{"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. Poniższe czynności usuną Alana ze ścieżki naszych users :

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Udane żądanie DELETE będzie wskazywane przez kod stanu HTTP 200 OK z odpowiedzią zawierającą JSON null .

Parametry URI

REST API akceptuje następujące parametry URI podczas zapisywania danych do bazy danych:

autoryzacja

Parametr żądania auth umożliwia dostęp do danych chronionych regułami bezpieczeństwa bazy danych czasu rzeczywistego Firebase i jest obsługiwany przez wszystkie typy żądań. Argumentem może być nasz klucz tajny aplikacji Firebase lub token uwierzytelniający, który omówimy w sekcji autoryzacji użytkownika . W poniższym przykładzie wysyłamy żądanie POST z parametrem auth , gdzie CREDENTIAL jest naszym sekretem aplikacji Firebase lub tokenem uwierzytelniającym:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

wydrukować

Parametr print pozwala nam określić format naszej odpowiedzi z bazy danych. Dodanie print=pretty do naszego żądania spowoduje zwrócenie danych w formacie czytelnym dla człowieka. print=pretty jest obsługiwany przez żądania GET , PUT , POST , PATCH i DELETE .

Aby ukryć wyjście z serwera podczas zapisywania danych, możemy dodać print=silent do naszego żądania. Wynikowa odpowiedź będzie pusta i oznaczona kodem stanu HTTP 204 No Content , jeśli żądanie zakończy się pomyślnie. print=silent jest obsługiwany przez żądania GET , PUT , POST i PATCH .

Zapisywanie wartości serwera

Wartości serwera można zapisać w lokalizacji przy użyciu wartości zastępczej, która jest obiektem z pojedynczym kluczem ".sv" . Wartość tego klucza jest typem wartości serwera, którą chcemy ustawić. Na przykład, aby ustawić znacznik czasu podczas tworzenia użytkownika, możemy wykonać następujące czynności:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" jest jedyną obsługiwaną wartością serwera i określa czas w milisekundach od epoki systemu UNIX.

Poprawa wydajności zapisu

Jeśli zapisujemy duże ilości danych w bazie danych, możemy użyć parametru print=silent aby poprawić wydajność zapisu i zmniejszyć wykorzystanie przepustowości. W normalnym zachowaniu podczas zapisu serwer odpowiada zapisanymi danymi JSON. W przypadku określenia print=silent serwer natychmiast zamyka połączenie po odebraniu danych, zmniejszając wykorzystanie przepustowości.

W przypadkach, gdy wysyłamy wiele żą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 API REST zwróci kody błędów w następujących okolicznościach:

Kody stanu HTTP
400 Złe żądanie

Jeden z następujących warunków błędu:

  • Nie można przeanalizować danych PUT lub POST .
  • Brak danych PUT lub POST .
  • Żądanie próbuje PUT lub POST danych, które są zbyt duże.
  • Wywołanie interfejsu API REST zawiera nieprawidłowe nazwy elementów podrzędnych jako część ścieżki.
  • Ścieżka wywołania interfejsu API REST jest za długa.
  • Żądanie zawiera nierozpoznaną wartość serwera.
  • Indeks zapytania nie jest zdefiniowany w regułach bezpieczeństwa bazy danych czasu rzeczywistego Firebase .
  • Żądanie nie obsługuje jednego z podanych parametrów zapytania.
  • Żądanie miesza parametry zapytania z płytkim żądaniem GET .
401 Nieautoryzowane

Jeden z następujących warunków błędu:

404 Nie znaleziono Nie znaleziono określonej bazy danych Firebase.
500 Wewnętrzny błąd serwera Serwer zwrócił błąd. Zobacz komunikat o błędzie, aby uzyskać więcej informacji.
503 Usługa niedostępna Określona baza danych czasu rzeczywistego Firebase jest tymczasowo niedostępna, co oznacza, że ​​nie podjęto próby żądania.

Zabezpieczanie danych

Firebase ma język bezpieczeństwa, który pozwala nam określić, którzy użytkownicy mają dostęp do odczytu i zapisu do różnych węzłów naszych danych. Możesz przeczytać więcej na ten temat w Regułach bezpieczeństwa bazy danych czasu rzeczywistego .

Teraz, gdy omówiliśmy zapisywanie danych, w następnej sekcji możemy dowiedzieć się, jak pobrać nasze dane z bazy danych Firebase za pośrednictwem interfejsu API REST.