Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Trabalhar com listas de dados em plataformas Apple

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Obter um FIRDatabaseReference

Para ler ou gravar dados do banco de dados, você precisa de uma instância de FIRDatabaseReference :

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

Observação: este produto Firebase não está disponível no destino App Clip.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

Ler e escrever listas

Anexar a uma lista de dados

Use o método childByAutoId para anexar dados a uma lista em aplicativos multiusuários. O método childByAutoId gera uma chave exclusiva sempre que um novo filho é adicionado à referência especificada do Firebase. Usando essas chaves geradas automaticamente para cada novo elemento na lista, vários clientes podem adicionar filhos ao mesmo local ao mesmo tempo sem conflitos de gravação. A chave exclusiva gerada por childByAutoId é baseada em um carimbo de data/hora, portanto, os itens da lista são automaticamente ordenados em ordem cronológica.

Você pode usar a referência aos novos dados retornados pelo método childByAutoId para obter o valor da chave gerada automaticamente pelo filho ou definir dados para o filho. Chamar getKey em uma referência childByAutoId retorna a chave gerada automaticamente.

Você pode usar essas chaves geradas automaticamente para simplificar o achatamento de sua estrutura de dados. Para obter mais informações, consulte o exemplo de fan-out de dados.

Ouvir eventos filhos

Os eventos filho são acionados em resposta a operações específicas que acontecem com os filhos de um nó de uma operação, como um novo filho adicionado por meio do método childByAutoId ou um filho sendo atualizado por meio do método updateChildValues .

Tipo de evento Uso típico
FIRDataEventTypeChildAdded Recupere listas de itens ou ouça adições a uma lista de itens. Esse evento é acionado uma vez para cada filho existente e novamente sempre que um novo filho é adicionado ao caminho especificado. O ouvinte recebe um instantâneo contendo os dados do novo filho.
FIRDataEventTypeChildChanged Ouça as alterações nos itens de uma lista. Este evento é acionado sempre que um nó filho é modificado. Isso inclui quaisquer modificações nos descendentes do nó filho. O instantâneo passado para o ouvinte de eventos contém os dados atualizados para o filho.
FIRDataEventTypeChildRemoved Ouça os itens sendo removidos de uma lista. Este evento é acionado quando um filho imediato é removido. O instantâneo passado para o bloco de retorno de chamada contém os dados do filho removido.
FIRDataEventTypeChildMoved Ouça as alterações na ordem dos itens em uma lista ordenada. Este evento é acionado sempre que uma atualização causa o reordenamento do filho. Ele é usado com dados ordenados por queryOrderedByChild ou queryOrderedByValue .

Cada um deles juntos pode ser útil para ouvir alterações em um nó específico em um banco de dados. Por exemplo, um aplicativo de blog social pode usar esses métodos juntos para monitorar a atividade nos comentários de uma postagem, conforme mostrado abaixo:

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
// 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

Observação: este produto Firebase não está disponível no destino App Clip.
// 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];
 }];

Ouça eventos de valor

Embora a escuta de eventos filho seja a maneira recomendada de ler listas de dados, há situações em que a escuta de eventos de valor em uma referência de lista é útil.

Anexar um observador FIRDataEventTypeValue a uma lista de dados retornará toda a lista de dados como um único DataSnapshot, que você pode fazer um loop para acessar filhos individuais.

Mesmo quando há apenas uma única correspondência para a consulta, o instantâneo ainda é uma lista; ele contém apenas um único item. Para acessar o item, você precisa fazer um loop sobre o resultado:

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

Observação: este produto Firebase não está disponível no destino App Clip.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

Esse padrão pode ser útil quando você deseja buscar todos os filhos de uma lista em uma única operação, em vez de ouvir eventos adicionais de filhos adicionados.

Classificando e filtrando dados

Você pode usar a classe FIRDatabaseQuery do Realtime Database para recuperar dados classificados por chave, por valor ou pelo valor de um filho. Você também pode filtrar o resultado classificado para 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 order-by para determinar como os resultados são ordenados:

Método Uso
queryOrderedByKey Ordene os resultados por chaves filhas.
queryOrderedByValue Ordene os resultados por valores filhos.
queryOrderedByChild Ordene os resultados pelo valor de uma chave filho especificada ou caminho filho aninhado.

Você só pode usar um método de ordem por vez. Chamar um método order-by várias vezes na mesma consulta gera um erro.

O exemplo a seguir demonstra como você pode recuperar uma lista das principais postagens de um usuário classificadas por sua contagem de estrelas:

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Objective-C

Observação: este produto Firebase não está disponível no destino App Clip.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

Esta consulta recupera as postagens do usuário do caminho no banco de dados com base em seu ID de usuário, ordenado pelo número de estrelas que cada postagem recebeu. Essa técnica de usar IDs como chaves de índice é chamada de distribuição de dados, você pode ler mais sobre ela 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. As consultas também podem ser ordenadas por filhos aninhados, caso você tenha dados parecidos 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 de metrics , especificando o caminho relativo para o filho aninhado em nossa chamada queryOrderedByChild .

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

Observação: este produto Firebase não está disponível no destino App Clip.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

Para obter mais informações sobre como outros tipos de dados são ordenados, consulte Como os dados de consulta são ordenados .

Filtrando dados

Para filtrar dados, você pode combinar qualquer um dos métodos limit ou range com um método order-by ao construir uma consulta.

Método Uso
queryLimitedToFirst Define o número máximo de itens a serem retornados desde o início da lista ordenada de resultados.
queryLimitedToLast Define o número máximo de itens a serem retornados do final da lista ordenada de resultados.
queryStartingAtValue Retorna itens maiores ou iguais à chave ou valor especificado, dependendo do método de ordenação escolhido.
queryStartingAfterValue Retorna itens maiores que a chave ou valor especificado, dependendo do método de ordenação escolhido.
queryEndingAtValue Retorna itens menores ou iguais à chave ou valor especificado, dependendo do método de ordenação escolhido.
queryEndingBeforeValue Retorna itens menores que a chave ou valor especificado, dependendo do método de ordenação escolhido.
queryEqualToValue Retorna itens iguais à chave ou valor especificado, dependendo do método de ordenação escolhido.

Ao contrário dos métodos de ordem, você pode combinar várias funções de limite ou intervalo. Por exemplo, você pode combinar os métodos queryStartingAtValue e queryEndingAtValue para limitar os resultados a um intervalo de valores especificado.

Limite o número de resultados

Você pode usar os métodos queryLimitedToFirst e queryLimitedToLast 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, receberá inicialmente apenas até 100 retornos de chamada FIRDataEventTypeChildAdded . Se você tiver menos de 100 itens armazenados em seu banco de dados do Firebase, um retorno de chamada FIRDataEventTypeChildAdded acionado para cada item.

À medida que os itens mudam, você recebe retornos de chamada FIRDataEventTypeChildAdded para itens que entram na consulta e retornos de chamada FIRDataEventTypeChildRemoved para itens que saem dela para que o número total permaneça em 100.

O exemplo a seguir demonstra como um exemplo de aplicativo de blog pode recuperar uma lista das 100 postagens mais recentes de todos os usuários:

Rápido

Observação: este produto Firebase não está disponível no destino App Clip.
// 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

Observação: este produto Firebase não está disponível no destino App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

Filtre por chave ou valor

Você pode usar queryStartingAtValue , queryStartingAfterValue , queryEndingAtValue , queryEndingBeforeValue e queryEqualToValue para escolher pontos de início, término e equivalência arbitrários para consultas. Isso pode ser útil para paginar dados ou localizar itens com filhos que tenham um valor específico.

Como os dados da consulta são ordenados

Esta seção explica como os dados são classificados por cada um dos métodos order-by na classe FIRDatabaseQuery .

queryOrderedByKey

Ao usar queryOrderedByKey para classificar seus dados, os dados são retornados em ordem crescente por chave.

  1. Filhos com uma chave que pode 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 vêm em seguida, classificados lexicograficamente em ordem crescente.

queryOrderedByValue

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

queryOrderedByChild

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

  1. Os filhos com um valor nil para a chave filha especificada vêm primeiro.
  2. Filhos com um valor false para a chave filha especificada vêm em seguida. Se vários filhos tiverem um valor false , eles serão classificados lexicograficamente por chave.
  3. Filhos com um valor true para a chave filha especificada vêm em seguida. Se vários filhos tiverem um valor true , eles serão classificados lexicograficamente por chave.
  4. Filhos com um valor numérico vêm em seguida, 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. As 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. Os objetos vêm por último e são classificados lexicograficamente por chave em ordem crescente.

Desanexar ouvintes

Os observadores não param automaticamente de sincronizar os 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 reterá todos os objetos capturados no fechamento do manipulador de eventos, o que pode causar vazamentos de memória. Quando um observador não for mais necessário, remova-o passando o FIRDatabaseHandle associado ao método removeObserverWithHandle .

Quando você adiciona um bloco de retorno de chamada a uma referência, um FIRDatabaseHandle é retornado. Esses identificadores podem ser usados ​​para remover o bloco de retorno de chamada.

Se vários ouvintes tiverem sido adicionados a uma referência de banco de dados, cada ouvinte será chamado quando um evento for gerado. Para interromper a sincronização de dados nesse local, você deve remover todos os observadores em um local chamando o método removeAllObservers .

Chamar removeObserverWithHandle ou removeAllObservers em um ouvinte não remove automaticamente os ouvintes registrados em seus nós filhos; você também deve acompanhar essas referências ou identificadores para removê-los.

Próximos passos