Como ter uma FIRDatabaseReference
Para ler ou gravar dados no banco de dados, você precisa de uma instância de
FIRDatabaseReference
:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];
Como ler e gravar listas
Anexar a uma lista de dados
Use o método childByAutoId
para anexar dados a uma lista em aplicativos
de vários usuários. O método childByAutoId
gera uma chave exclusiva sempre que um novo
filho é adicionado a uma referência específica do Firebase. Ao usar essas
chaves geradas automaticamente para cada novo elemento da lista, vários clientes poderão adicionar
filhos no mesmo local simultaneamente sem criar conflitos de gravação. A
chave exclusiva gerada por childByAutoId
é baseada em um carimbo de data/hora. Portanto, os itens da lista
são organizados automaticamente em ordem cronológica.
Use a referência aos novos dados retornados pelo método childByAutoId
para receber o valor da chave filha que foi gerada automaticamente ou para definir dados para o filho.
Chamar getKey
em uma referência childByAutoId
retorna a chave gerada automaticamente.
Você pode usar essas chaves para simplificar sua estrutura de dados. Para saber mais, consulte o exemplo de distribuição de dados.
Detectar eventos filho
Eventos filhos são acionados em resposta a operações específicas que ocorrem nos
filhos de um nó de uma operação, como a adição de um novo filho por meio do
método childByAutoId
ou a atualização de um filho pelo método updateChildValues
.
Tipo de evento | Uso normal |
---|---|
FIRDataEventTypeChildAdded |
Recuperar listas de itens ou detectar adições a uma lista de itens. Este evento é acionado uma vez para cada filho e sempre que um novo filho for adicionado ao caminho especificado. O listener recebe um snapshot que contém os dados do novo filho. |
FIRDataEventTypeChildChanged |
Detectar mudanças em itens de uma lista. Este evento é acionado sempre que um nó filho é modificado. Isso inclui modificações nos descendentes do nó filho. O snapshot transmitido para o listener de eventos contém os dados atualizados do filho. |
FIRDataEventTypeChildRemoved |
Detectar itens sendo removidos de uma lista. Esse evento é acionado quando um filho imediato é removido. O snapshot transmitido ao bloco de retorno de chamada contém os dados do filho removido. |
FIRDataEventTypeChildMoved |
Detectar mudanças na ordem dos itens em uma lista ordenada.
Este evento é acionado sempre que uma atualização causa mudança na ordem do
filho. Ele é usado com dados ordenados por queryOrderedByChild
ou queryOrderedByValue .
|
Juntos, cada um desses métodos pode ser útil para detectar alterações em um nó específico de um banco de dados. Por exemplo, um app de blog com recursos sociais pode usar esses métodos em conjunto para monitorar atividade nos comentários de uma postagem, conforme mostrado abaixo:
Swift
// Listen for new comments in the Firebase database commentsRef.observe(.childAdded, with: { (snapshot) -> Void in self.comments.append(snapshot) self.tableView.insertRows( at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic ) }) // Listen for deleted comments in the Firebase database commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in let index = self.indexOfMessage(snapshot) self.comments.remove(at: index) self.tableView.deleteRows( at: [IndexPath(row: index, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic ) })
Objective-C
// Listen for new comments in the Firebase database [_commentsRef observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) { [self.comments addObject:snapshot]; [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments] ] withRowAnimation:UITableViewRowAnimationAutomatic]; }]; // Listen for deleted comments in the Firebase database [_commentsRef observeEventType:FIRDataEventTypeChildRemoved withBlock:^(FIRDataSnapshot *snapshot) { int index = [self indexOfMessage:snapshot]; [self.comments removeObjectAtIndex:index]; [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]] withRowAnimation:UITableViewRowAnimationAutomatic]; }];
Detectar eventos de valor
Detectar eventos filho é a maneira recomendada para ler listas de dados. Porém, há situações em que é útil detectar eventos de valor em uma referência de lista.
Anexar um observador FIRDataEventTypeValue
a uma lista de dados retornará a
lista inteira de dados como um DataSnapshot único que pode ser retornado para
acessar filhos individuais.
Mesmo quando há apenas uma correspondência para a consulta, o snapshot ainda é uma lista, mas contém somente um item. Para acessar o item, é necessário retornar o resultado:
Swift
_commentsRef.observe(.value) { snapshot in for child in snapshot.children { ... } }
Objective-C
[_commentsRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // Loop over children NSEnumerator *children = [snapshot children]; FIRDataSnapshot *child; while (child = [children nextObject]) { // ... } }];
Este padrão pode ser útil quando você quiser buscar todos os filhos de uma lista em uma única operação em vez de detectar eventos mais filhos.
Como classificar e filtrar dados
É possível usar a classe FIRDatabaseQuery
do Realtime Database para recuperar dados classificados
por chave, valor ou valor de filho. Também é possível filtrar
o resultado ordenado por um número específico de resultados ou um intervalo de chaves ou
valores.
Ordenar dados
Para recuperar dados ordenados, comece especificando um dos métodos de ordenação para determinar como os resultados são ordenados:
Método | Uso |
---|---|
queryOrderedByKey
| Ordenar resultados por chaves filhas. |
queryOrderedByValue |
Ordenar resultados por valores filhos. |
queryOrderedByChild |
Ordenar resultados pelo valor de uma chave filha específica ou caminho filho aninhado. |
Você só pode usar um método de ordenação por vez. Chamar um método de ordenação várias vezes na mesma consulta causa um erro.
O exemplo a seguir demonstra como você pode recuperar uma lista das principais postagens de um usuário ordenadas pela contagem de estrelas:
Swift
// My top posts by number of stars let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")
Objective-C
// My top posts by number of stars FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"] child:[super getUid]] queryOrderedByChild:@"starCount"];
Essa consulta recupera as postagens do usuário a partir do caminho do banco de dados conforme o ID do usuário, ordenadas pelo número de estrelas recebidas pelas postagens. Essa técnica de usar IDs como chaves de indexação é chamada de distribuição de dados e é explicada em mais detalhes em Estruturar seu banco de dados.
A chamada para o método queryOrderedByChild
especifica a chave filha para ordenar
os resultados. Neste exemplo, as postagens são classificadas pelo valor do
filho "starCount"
em cada postagem. Também é possível ordenar as consultas por filhos
aninhados, caso os dados se pareçam com estes:
"posts": { "ts-functions": { "metrics": { "views" : 1200000, "likes" : 251000, "shares": 1200, }, "title" : "Why you should use TypeScript for writing Cloud Functions", "author": "Doug", }, "android-arch-3": { "metrics": { "views" : 900000, "likes" : 117000, "shares": 144, }, "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)", "author": "Doug", } },
Nesse caso, podemos ordenar nossos elementos de lista por valores aninhados na
chave metrics
. Para isso, é preciso especificar o caminho relacionado ao filho aninhado em
nossa chamada de queryOrderedByChild
.
Swift
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Objective-C
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];
Para mais informações sobre a ordenação de outros tipos de dados, consulte Como os dados de consulta são ordenados.
Filtrar dados
Para filtrar dados, combine um dos métodos de limite ou de intervalo com um método de ordenação ao criar uma consulta.
Método | Uso |
---|---|
queryLimitedToFirst |
Definir o número máximo de itens para retornar a partir do início da lista ordenada de resultados. |
queryLimitedToLast |
Definir o número máximo de itens para retornar a partir do fim da lista ordenada de resultados. |
queryStartingAtValue |
Retornar itens maiores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
queryStartingAfterValue |
Retornar itens maiores do que a chave ou o valor especificado, dependendo do método de ordenação escolhido. |
queryEndingAtValue |
Retornar itens inferiores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
queryEndingBeforeValue |
Retornar itens inferiores à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
queryEqualToValue |
Retornar itens iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
Ao contrário dos métodos de ordenação, você pode combinar várias funções de limite ou de intervalo.
Por exemplo, combine os métodos queryStartingAtValue
e queryEndingAtValue
para limitar
os resultados a um intervalo especificado de valores.
Limitar o número de resultados
Os parâmetros queryLimitedToFirst
e queryLimitedToLast
podem ser usados para definir um
número máximo de filhos a serem sincronizados para um determinado retorno de chamada. Por exemplo, se
você usar queryLimitedToFirst
para definir um limite de 100, inicialmente receberá até
100 retornos de chamada FIRDataEventTypeChildAdded
apenas. Se você tiver menos de 100 itens armazenados no
banco de dados do Firebase, um retorno de chamada FIRDataEventTypeChildAdded
será acionado para cada item.
Conforme os itens forem alterados, você receberá retornos de chamada FIRDataEventTypeChildAdded
para os itens que entrarem na
consulta e retornos de chamada FIRDataEventTypeChildRemoved
para os itens que saírem da consulta para que
o número total permaneça 100.
No exemplo a seguir, demonstramos como um app de blog pode recuperar uma lista das 100 postagens mais recentes de todos os usuários:
Swift
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!
Objective-C
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];
Filtrar por chave ou valor
O uso de queryStartingAtValue
, queryStartingAfterValue
, queryEndingAtValue
, queryEndingBeforeValue
e queryEqualToValue
possibilitará escolher pontos arbitrários
de início e fim para as consultas. Isso pode ser útil para
paginar dados ou encontrar itens com filhos que tenham um valor específico.
Como os dados de consultas são ordenados
Nesta seção, é explicado como os dados são classificados por cada um dos métodos de ordenação na
classe FIRDatabaseQuery
.
queryOrderedByKey
Ao usar queryOrderedByKey
para classificar seus dados, eles serão retornados em ordem crescente
por chave.
- Filhos com uma chave que possa ser analisada como um número inteiro de 32 bits vêm primeiro, ordenados em ordem crescente.
- Filhos com um valor de string como chave são os próximos, ordenados lexicograficamente em ordem crescente.
queryOrderedByValue
Ao usar queryOrderedByValue
, os filhos serão ordenados pelo próprio valor. Os critérios
de ordenação são os mesmos de queryOrderedByChild
, com a exceção de que o valor usado é o do nó,
e não o de uma chave filha especificada.
queryOrderedByChild
Ao usar queryOrderedByChild
, os dados que contêm a chave filha especificada serão
ordenados desta maneira:
- Filhos com um valor
nil
para a chave filha especificada são os primeiros. - Filhos com um valor
false
para a chave filha especificada são os próximos. Se vários filhos tiverem um valorfalse
, eles serão classificados lexicograficamente pela chave. - Filhos com um valor
true
para a chave filha especificada são os próximos. Se vários filhos tiverem um valortrue
, eles serão classificados lexicograficamente pela chave. - Filhos com um valor numérico são os próximos, classificados em ordem crescente. Se vários filhos tiverem o mesmo valor numérico para o nó filho especificado, eles serão classificados por chave.
- Strings vêm depois dos números e são classificadas lexicograficamente em ordem crescente. Se vários filhos tiverem o mesmo valor para o nó filho especificado, eles serão ordenados lexicograficamente por chave.
- Objetos vêm por último e são classificados lexicograficamente pela chave em ordem crescente.
Remover listeners
Os observadores não interrompem automaticamente a sincronização de dados quando você sai de um
ViewController
. Se um observador não for removido corretamente, ele continuará sincronizando dados com a memória local e manterá quaisquer objetos capturados no manipulador de eventos, o que pode causar vazamentos de memória. Quando um observador não for mais necessário, remova-o ao transmitir
o FIRDatabaseHandle
associado ao método removeObserverWithHandle
.
Ao adicionar um bloco de retorno de chamada a uma referência, um FIRDatabaseHandle
é retornado.
Esses handles podem ser usados para remover esse bloco.
Se vários listeners são adicionados a uma referência de banco de dados, cada um é
chamado quando um evento é acionado. Para interromper a sincronização de dados nesse local,
remova todos os observadores em um local chamando o método
removeAllObservers
.
Chamar removeObserverWithHandle
ou removeAllObservers
em um listener não
remove automaticamente os listeners registrados nos nós filhos. É preciso também
encontrar essas referências ou identificadores para removê-los.