Em um banco de dados em tempo real (no Firebase), tenho as seguintes regras para a coleção chamada Resource:
{
"rules": {
....
"Resource": {
".read": true,
".indexOn": ["FieldOne","FieldTwo"]
},
....
}
}
As coisas funcionam do jeito que eu desejo. Gostaria, no entanto, de fazer algumas melhorias.
Aqui está meu problema. Neste ponto, posso adicionar um documento à coleção a partir da CLI usando um comando como este:
firebase database:push /..path../Resource --data '{"FieldOne":"field-1-value","FieldTwo":"field-2-value"}'
Claro que também posso adicionar documentos de diferentes maneiras. Mas meu problema é que posso repetir o mesmo comando acima e adicionar novamente o mesmo documento na coleção Resource.
Quero saber como alterar minhas regras para evitar a possibilidade de adicionar dados duplicados.
Exatamente isso é o que eu gostaria, depois de executar o comando acima, eu ainda deveria conseguir inserir esses documentos na coleção:
{"FieldOne":"field-3-value","FieldTwo":"field-4-value"}
{"FieldOne":"field-1-value","FieldTwo":"field-5-value"}
{"FieldOne":"field-7-value","FieldTwo":"field-2-value"}
Mas, eu não deveria conseguir inserir este:
{"FieldOne":"field-1-value","FieldTwo":"field-2-value"}
Eu poderia, é claro, escrever código para controlar o que está chegando, no caso de funções de nuvem ou no caso de dados sendo digitados por meio de uma interface da web. Mas esse não é o ponto da presente questão. Eu só quero saber se há uma maneira inteligente de configurar as regras para evitar a possibilidade de dados indesejados começarem.
O Firebase Realtime Database não tem suporte integrado para evitar valores duplicados.
Por outro lado, as chaves em um nó são garantidas para sempre serem únicas . Isso significa que você normalmente vai querer armazenar os valores que você quer que sejam únicos nas chaves no banco de dados/JSON, em vez de em valores.
Vamos primeiro olhar para o que acontece atualmente
Quando você chama push/POST, o Firebase gera chaves exclusivas
Quando você chama
push
o Firebase (ouPOST
sua REST API), o banco de dados ou SDK gera uma chave exclusiva para você. Então, no seu exemplo com os três nós filhos (como Doug comentou, o Firebase Realtime Database não tem conceito de documentos ou coleções, e usarei a terminologia correta aqui para evitar confusão), o JSON será, na verdade, algo como isto:Essas chaves que começam com a
-
são as chaves push que o Firebase gera. Então, se você chamarpush
/POST novamente (com valores diferentes ou iguais ), ele gera outra chave exclusiva.Gerar uma chave com base nos valores que devem ser únicos
Para evitar duplicatas, você deve garantir que a chave seja uma apresentação dos valores - para que, se você passar os mesmos valores uma segunda vez, obtenha a mesma chave.
Uma maneira de fazer isso é simplesmente concatenar os valores e usar isso como a chave. Então isso transformaria o JSON acima em:
Nessa estrutura, se você passar os mesmos valores para o banco de dados, ele terá a mesma chave. E como dito no começo: as chaves em um nó são garantidas para sempre serem únicas. Então, dependendo da operação que você usar, a segunda gravação dos mesmos valores/chave será rejeitada ou sobrescreverá os valores existentes (com os mesmos valores, então é uma operação sem efeito).
Usando
set
/PUT em vez depush
/POSTPara escrever a estrutura acima onde você especifica sua própria chave, você precisa usar a
set
operação /PUT em vez de usarpush
/POST. Então seu exemplo com o Firebase CLI se tornaria:Aqui você pode ver que agora:
database:set
em vez dedatabase:push
field-1-value_field-2-value
chave), em vez de apenas informar ao nó pai onde queremos adicionar algo novo.Este tópico já foi abordado antes, então recomendo também conferir: