Para que serve o tipo de dados 'Referência' do Firebase Firestore?

189

Estou apenas explorando o novo Firebase Firestore e ele contém um tipo de dados chamado reference. Não está claro para mim o que isso faz.

  • É como chave estrangeira?
  • Pode ser usado para apontar para uma coleção localizada em outro lugar?
  • Se referencefor uma referência real, posso usá-la para consultas? Por exemplo, posso ter uma referência que aponte diretamente para o usuário, em vez de armazenar o userId em um campo de texto? E posso usar esta referência de usuário para consultar?
Jürgen Brandstetter
fonte
18
Eu acho que este vídeo da equipe do firebase o detalha: youtube.com/watch?v=Elg2zDVIcLo (assista a partir de 4:36)
Adarsh

Respostas:

91

As referências são muito parecidas com chaves estrangeiras.

Os SDKs lançados atualmente não podem armazenar referências a outros projetos. Dentro de um projeto, as referências podem apontar para qualquer outro documento em qualquer outra coleção.

Você pode usar referências em consultas como qualquer outro valor: para filtragem, pedido e paginação (startAt / startAfter).

Diferentemente das chaves estrangeiras em um banco de dados SQL, as referências não são úteis para executar junções em uma única consulta. Você pode usá-los para pesquisas dependentes (que parecem se associar), mas tenha cuidado porque cada salto resultará em outra viagem de ida e volta ao servidor.

Gil Gilbert
fonte
9
Por favor, você pode compartilhar possíveis casos de uso? É possível consultar os campos nessa referência? Por exemplo, eu tenho uma friendscoleção listando todos os meus amigos ( friends/myId). Então, faço referência a este documento no friendscampo de outro documento ( group/groupId). Eu gostaria de exibir apenas meus amigos que estão nesse grupo, fazendo algo parecido com isto: where('friends.myId', '==', true).
Will
108
Aliás, pode ser útil atualizar os documentos para incluir um exemplo de adição de um tipo de referência.
Will
11
Não consigo encontrar nenhuma informação sobre isso? Isso vai mudar minha estrutura banco de dados inteiro, eu preciso saber mais ...
Ruben
3
você tem um exemplo (de preferência rápido) de como consultar usando referência? No momento, eu posso fazer isso armazenando o uid bruto como uma string, mas isso não parece certo.
Mickey Cheong
6
Estou precisando alterar todos os meus tipos de referência para seqüências de caracteres, porque a consulta sempre falha com um tipo de referência. Eu literalmente não consigo encontrar nada sobre como consulta por tipo de referência :( se alguém descobrir como consulta por tipos de referência deixe-me saber ...
Sam Trent
133

Adicionando abaixo o que funcionou para mim usando referências no Firestore.

Como as outras respostas dizem, é como uma chave estrangeira. O atributo de referência não retorna os dados do documento de referência. Por exemplo, eu tenho uma lista de produtos, com uma referência userRef como um dos atributos no produto. Obter a lista de produtos, fornece a referência do usuário que criou esse produto. Mas não me fornece os detalhes do usuário nessa referência. Eu usei outro back-end como um serviço com ponteiros antes, que possui um sinalizador "preencher: true" que devolve os detalhes do usuário, em vez de apenas o ID de referência do usuário, o que seria ótimo ter aqui (esperamos que uma melhoria futura )

Abaixo está um código de exemplo que eu usei para definir a referência, além de obter a lista de coleção de produtos e obter os detalhes do usuário a partir do ID de referência do usuário.

Defina uma referência em uma coleção:

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

Obtenha uma coleção (produtos) e todas as referências em cada documento (detalhes do usuário):

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

Espero que isto ajude

Ben Cochrane
fonte
3
Obrigado por compartilhar! Eu acho que há um erro de digitação na primeira linha da parte Get e deve ser db.collection('products').get(). Você já tentou obter o usuário diretamente? Eu acho que newItem.userRef.get()deve funcionar em vez dedb.collection("users").doc(newItem.userRef.id).get()
Sergey Nefedyev
53
Antes de tudo, obrigado pelo exemplo. Espero que eles adicionem um "preencher: true" para o futuro. Caso contrário, salvar uma referência é um pouco inútil. O mesmo poderia ter sido feito simplesmente salvando a uidreferência e via ela.
Jürgen Brandstetter
4
Obrigado pelo exemplo! Mas qual é o sentido de armazenar o tipo de referência se não houver um tipo de opção "preencher" quando consultamos o documento? Se houver uma opção popular que alguém conheça, entre em contato.
Harshil Shah
18
Então, na verdade, não é como uma chave estrangeira. Para mim, basicamente não faz nada - qual é o sentido de ter referencese não podemos usá-lo como uma verdadeira chave estrangeira deve funcionar?
Jean d'arme
14
Portanto, a única vantagem de um referenceover a stringé que você pode chamar get()a referência diretamente. Ainda não é muito útil. Espero que eles adicionem uma opção para preencher automaticamente as referências com os objetos correspondentes!
morgler
16

Para quem procura uma solução Javascript para consulta por referência - o conceito é que você precisa usar um objeto 'referência de documento' na instrução de consulta

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(Parabéns à resposta aqui: https://stackoverflow.com/a/53141199/1487867 )

Aswin Kumar
fonte