Teste o Cloud Firestore: conheça o banco de dados escalonável e flexível do Firebase e do Google Cloud Platform. Saiba mais sobre o Cloud Firestore.

Trabalhar com listas de dados no iOS

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

Adicionar itens a uma lista de dados

Use o método childByAutoId para anexar dados a uma lista em apps 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 uma marcação de data e hora, portanto, os itens da lista são organizados automaticamente em ordem cronológica.

Você pode usar a referência aos novos dados retornados pelo método childByAutoId para obter o valor da chave filho, que foi gerada automaticamente, ou para definir dados para o filho. Chamar getKey em uma referência childByAutoId retorna o valor da 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 filhos

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 por meio do método updateChildValues.

Tipo de evento Uso típico
FIRDataEventTypeChildAdded Recuperar listas de itens ou detectar adições a uma lista de itens. Este evento é acionado uma vez para cada filho existente e sempre que um novo filho for adicionado ao caminho especificado. O listener recebe um instantâneo 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 instantâneo transmitido para o retorno de chamada do evento contém os dados atualizados do filho.
FIRDataEventTypeChildRemoved Detecta itens sendo removidos de uma lista. Este evento é acionado quando um filho imediato é removido.O instantâneo transmitido para o bloco do retorno de chamada contém os dados do filho removido.
FIRDataEventTypeChildMoved Detecta 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. É usado com dados ordenados por queryOrderedByChild ou queryOrderedByValue.

Juntos, cada um desses métodos pode ser útil para detectar mudanças em um nó específico de um banco de dados. Por exemplo, um app de blog de mídia social 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: UITableViewRowAnimation.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: UITableViewRowAnimation.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 você pode retornar para acessar filhos individuais.

Mesmo quando há apenas uma correspondência para a consulta, o instantâneo 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 filhos adicionais.

Classificar e filtrar dados

Você pode usar a classe FIRDatabaseQuery do Realtime Database para recuperar dados classificados por chave, valor, valor de filho ou prioridade. Também é possível filtrar o resultado classificado por um número específico de resultados ou um intervalo de chaves ou valores.

Classificar dados

Para recuperar dados classificados, comece especificando um dos métodos de ordenação para determinar como os resultados são ordenados:

Método Utilização
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 código do usuário, ordenadas pelo número de estrelas recebidas pelas postagens. Essa técnica de usar códigos 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 pela qual ordenar os resultados. Neste exemplo, as postagens são classificadas pelo valor do filho "starCount" em cada postagem. As consultas também podem ser ordenadas por filhos aninhados, caso seus 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, especificando 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.
queryEndingAtValue Retornar itens inferiores ou iguais à 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 alcance. Por exemplo, você pode combinar os métodos queryStartingAtValue e queryEndingAtValue para limitar os resultados a um determinado intervalo de valores.

Limitar o número de resultados

Você pode usar os métodos queryLimitedToFirst e queryLimitedToLast para definir um número máximo de filhos a ser sincronizado a um determinado retorno de chamada. Por exemplo, se você usar queryLimitedToFirst para definir um limite de 100, inicialmente receberá apenas até 100 retornos de chamada FIRDataEventTypeChildAdded. Se você tiver menos de 100 itens armazenados no banco de dados do Firebase, um retorno de chamada de 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

Você pode usar queryStartingAtValue, queryEndingAtValue e queryEqualToValue para escolher arbitrariamente pontos de início, encerramento e equivalência para consultas. Isso pode ser útil para paginar dados ou encontrar itens com filhos que tenham um valor específico.

Como dados de consultas são ordenados

Esta seção explica 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 são retornados em ordem crescente pelo nome da chave.

  1. Filhos com uma chave que possa ser analisada como um número inteiro de 32 bits vêm primeiro, classificados em ordem crescente.
  2. Filhos com um valor de string como chave são os seguintes, classificados lexicograficamente em ordem crescente.

queryOrderedByValue

Ao usar queryOrderedByValue, filhos são ordenados pelo valor. Os critérios de ordenação são os mesmos que os em queryOrderedByChild, mas o valor do nó é usado em vez do valor de uma chave filho especificada.

queryOrderedByChild

Ao usar queryOrderedByChild, os dados que contêm a chave filha especificada são ordenados da seguinte maneira:

  1. Filhos com um valor nil para a chave filha especificada são os primeiros.
  2. Filhos com um valor false para a chave filha especificada são os seguintes. Se vários filhos tiverem o valor false, eles serão classificados lexicograficamente por chave.
  3. Filhos com um valor true para a chave filha especificada são os próximos. Se vários filhos tiverem um valor true, eles serão classificados lexicograficamente pela chave.
  4. 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.
  5. 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.
  6. Objetos vêm por último e são classificados lexicograficamente pela chave em ordem crescente.

Desanexar 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. Quando ele não for mais necessário, remova-o passando o FIRDatabaseHandle associado para o método removeObserverWithHandle.

Quando um bloco de retorno de chamada é adicionado a uma referência, um FIRDatabaseHandle é devolvido. Esses identificadores 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, é necessário remover todos os observadores do local chamando o método removeAllObservers.

Chamar removeObserverWithHandle ou removeAllObservers em um listener não remove automaticamente os listeners registrados nesses nós filhos. É preciso rastrear as referências ou identificadores para removê-los.

Próximas etapas

Enviar comentários sobre…

Firebase Realtime Database
Precisa de ajuda? Acesse nossa página de suporte.