Receber uma referência do banco de dados
Para ler ou gravar dados no banco de dados, você precisa de uma instância de
DatabaseReference
:
DatabaseReference ref = FirebaseDatabase.instance.ref();
Como ler e gravar listas
Anexar a uma lista de dados
Use o método push()
para anexar dados a uma lista em aplicativos de vários usuários.
O método push()
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 podem adicionar filhos no mesmo local simultaneamente sem criar conflitos de gravação. A chave exclusiva gerada por push()
é 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 push()
para receber o valor da chave filha que foi gerada automaticamente ou para definir dados para o filho. A propriedade .key
de uma referência push()
contém 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.
Por exemplo, push()
pode ser usado para adicionar uma nova publicação à uma lista de postagens
em um aplicativo social:
DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
// ...
});
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 push()
ou a atualização de um filho pelo método update()
.
Evento | Uso normal |
---|---|
onChildAdded |
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. |
onChildChanged |
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 transferido ao listener do evento contém os dados atualizados do filho. |
onChildRemoved |
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. |
onChildMoved |
Detectar mudanças na ordem dos itens em uma lista ordenada. Os eventos onChildMudanças sempre seguem o evento onChildChanged que causou a mudança da ordem do item (com base no seu método atual "organizar por"). |
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 em rede social pode usar esses métodos em conjunto para monitorar a atividade nos comentários de uma postagem, conforme mostrado abaixo:
final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
// A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
// A comment has changed; use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
// A comment has been removed; use the key to determine if we are displaying
// this comment and if so remove it.
});
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 value
a uma lista de dados retornará
a lista inteira de dados como um snapshot único que você retorna 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:
myTopPostsQuery.onValue.listen((event) {
for (final child in event.snapshot.children) {
// Handle the post.
}
}, onError: (error) {
// Error.
});
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
É possível usar a classe Query
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 |
---|---|
orderByChild() |
Ordenar resultados pelo valor de uma chave filha específica ou caminho filho aninhado. |
orderByKey() |
Ordenar resultados por chaves filhas. |
orderByValue() |
Ordenar resultados por valores filhos. |
Você pode usar somente um método de ordenação por vez. Chamar um método de ordenação várias vezes na mesma consulta causa um erro.
No exemplo a seguir, demonstramos como você pode recuperar uma lista das principais postagens de um usuário ordenadas pela contagem de estrelas:
final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
.ref("user-posts/$myUserId")
.orderByChild("starCount");
Isso define uma consulta que, quando combinada com um listener filho, sincroniza o cliente com as postagens do usuário no caminho do banco de dados com base no ID do usuário, ordenadas pelo número de estrelas que cada postagem recebeu. 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 orderByChild()
especifica a chave filha para ordenar os resultados. Nesse caso, as postagens são classificadas pelo valor do respectivo filho de "starCount"
. 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 orderByChild()
.
final mostViewedPosts =
FirebaseDatabase.instance.ref('posts').orderByChild('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 |
---|---|
limitToFirst() |
Definir o número máximo de itens para retornar a partir do início da lista ordenada de resultados. |
limitToLast() |
Definir o número máximo de itens para retornar a partir do fim da lista ordenada de resultados. |
startAt() |
Retornar itens maiores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
startAfter() |
Retornar itens maiores do que a chave ou o valor especificado, dependendo do método de ordenação escolhido. |
endAt() |
Retornar itens inferiores ou iguais à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
endBefore() |
Retornar itens inferiores à chave ou ao valor especificado, dependendo do método de ordenação escolhido. |
equalTo() |
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 startAt()
e endAt()
para limitar
os resultados a um intervalo especificado de valores.
Limitar o número de resultados
Use os métodos limitToFirst()
e limitToLast()
para definir um número máximo de filhos a serem sincronizados para um determinado evento. Por exemplo, se limitToFirst()
for usado para definir um limite de 100, inicialmente serão recebidos até 100 eventos onChildAdded
. Se houver menos de 100 itens armazenados no seu banco de dados do Firebase, um evento onChildAdded
será disparado para cada item.
À medida que os itens são alterados, eventos onChildAdded
são recebidos para itens que entram na consulta e eventos onChildRemoved
para itens que saem dela, para que o número total permaneça em 100.
Veja a seguir uma demonstração de como o exemplo do app de blog define uma consulta para recuperar uma lista das 100 postagens mais recentes de todos os usuários:
final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);
Esse exemplo define somente uma consulta. Para sincronizar os dados, é necessário ter um listener anexado.
Filtrar por chave ou valor
O uso de startAt()
, startAfter()
, endAt()
, endBefore()
e equalTo()
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 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 Query
.
orderByChild
Ao usar orderByChild()
, os dados que contêm a chave filha especificada serão ordenados desta maneira:
- Filhos com um valor
null
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.
orderByKey
Ao usar orderByKey()
para classificar seus dados, eles serão retornados em ordem crescente pelo nome da 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.
orderByValue
Ao usar orderByValue()
, os filhos serão ordenados pelo próprio valor. Os critérios de ordenação são os mesmos de orderByChild()
, com a exceção de que o valor usado é o do nó, e não o de uma chave filha especificada.
Remover listeners
Para remover retornos de chamada, chame o método off()
na sua referência ao banco de dados do Firebase.
É possível remover um único listener passando-o como um parâmetro para off()
.
Chamar off()
no local sem argumentos remove todos os listeners desse
local.
Chamar off()
em um listener pai não remove automaticamente os listeners registrados nos nós filhos dele.
O off()
também precisa ser chamado nos listeners filhos
para remover a chamada de retorno.