Obter usuários por propriedade de nome usando o Firebase

129

Estou tentando criar um aplicativo onde posso obter / definir dados em contas de usuários específicos e fiquei tentado pelo Firebase.

O problema que tenho é que não sei como segmentar dados de usuários específicos quando minha estrutura se parece com isso:

Minha estrutura de dados descrita pelo texto abaixo.

online-b-cards
  - users
    - InnROTBVv6FznK81k3m
       - email: "hello@hello"
       - main:  "Hello world this is a text"
       - name:  "Alex"
       - phone: 12912912

Eu olhei em volta e realmente não consigo encontrar nada sobre como acessar dados individuais e muito menos quando recebem um hash aleatório como seu ID.

Como eu pegaria informações de usuários individuais com base em seus nomes? Se houver uma maneira melhor de fazer isso, por favor me diga!

Richard Bamford
fonte
tente isso: stackoverflow.com/questions/32886546/…
ugali soft 17/04/16

Respostas:

156

Anteriormente, o Firebase exigia que você gerasse seus próprios índices ou baixasse todos os dados em um local para encontrar e recuperar elementos que correspondessem a algum atributo filho (por exemplo, todos os usuários name === "Alex").

Em outubro de 2014, o Firebase lançou uma nova funcionalidade de consulta por meio do orderByChild()método, que permite fazer esse tipo de consulta com rapidez e eficiência. Veja a resposta atualizada abaixo.


Ao gravar dados no Firebase, você tem algumas opções diferentes que refletem diferentes casos de uso. Em um nível alto, o Firebase é um repositório de dados NoSQL estruturado em árvore e fornece algumas primitivas simples para gerenciar listas de dados:

  1. Escreva no Firebase com uma chave conhecida e exclusiva:

    ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
    
  2. Anexar às listas com uma chave gerada automaticamente que classificará automaticamente por hora escrita:

    ref.child('users').push({ "first_name": "rob", "age": 28 })
    
  3. Ouça as alterações nos dados por seu caminho exclusivo e conhecido:

    ref.child('users').child('123').on('value', function(snapshot) { ... })
    
  4. Filtre ou encomende dados em uma lista por valor de chave ou atributo :

    // Get the last 10 users, ordered by key
    ref.child('users').orderByKey().limitToLast(10).on('child_added', ...)
    
    // Get all users whose age is >= 25
    ref.child('users').orderByChild('age').startAt(25).on('child_added', ...)
    

Com a adição de orderByChild(), você não precisa mais criar seu próprio índice para consultas sobre atributos filho! Por exemplo, para recuperar todos os usuários com o nome "Alex":

ref.child('users').orderByChild('name').equalTo('Alex').on('child_added',  ...)

Engenheiro na Firebase aqui. Ao gravar dados no Firebase, você tem algumas opções diferentes que refletirão diferentes casos de uso de aplicativos. Como o Firebase é um repositório de dados NoSQL, você precisará armazenar seus objetos de dados com chaves exclusivas, para poder acessar diretamente esse item ou carregar todos os dados em um local específico e percorrer cada item para encontrar o nó que procura. . Consulte Gravando dados e gerenciando listas para obter mais informações.

Ao gravar dados no Firebase, você pode setusar dados usando um caminho único (definido) (ou seja a/b/c) ou pushdados em uma lista, o que gerará um ID único (ou seja a/b/<unique-id>) e permitirá que você classifique e consulte os itens nessa lista por tempo . O ID exclusivo que você vê acima é gerado ao ligar pushpara anexar um item à lista em online-b-cards/users.

Em vez de usar pushaqui, eu recomendaria usar sete armazenar os dados de cada usuário usando uma chave exclusiva, como o endereço de email do usuário. Em seguida, você pode acessar os dados do usuário diretamente, navegando online-b-cards/users/<email>através do Firebase JS SDK. Por exemplo:

function escapeEmailAddress(email) {
  if (!email) return false

  // Replace '.' (not allowed in a Firebase key) with ',' (not allowed in an email address)
  email = email.toLowerCase();
  email = email.replace(/\./g, ',');
  return email;
}

var usersRef = new Firebase('https://online-b-cards.firebaseio.com/users');
var myUser = usersRef.child(escapeEmailAddress('[email protected]')) 
myUser.set({ email: '[email protected]', name: 'Alex', phone: 12912912 });

Observe que, como o Firebase não permite certos caracteres nas referências (consulte Criando referências ), removemos .e substituímos por um ,no código acima.

Rob DiMarco
fonte
1
@RobDiMarco Você tem uma resposta para a pergunta postada abaixo por Stephen?
Charles Han
2
Hey @RobDiMarco. Embora sua sugestão de usar endereços de email como base para o ID ainda seja válida, pode valer a pena expandir sua resposta para apontar para o novo orderByChildrecurso. Dado que essa resposta aparece frequentemente como uma resposta relevante / relacionada, as pessoas são obrigadas a analisá-la e devem estar cientes dos novos recursos de consulta.
precisa
1
@FrankvanPuffelen Ótima idéia - obrigado pela observação. Vou atualizar isso hoje.
precisa
1
@Ced Infelizmente, não posso comentar o que está em andamento. Prometo que estamos trabalhando duro (isso sempre foi verdade), mas não podemos dar detalhes. A API do banco de dados é realmente restritiva em alguns aspectos, e fazemos isso deliberadamente apenas para expor métodos para os quais podemos garantir certos níveis de desempenho. É por isso que não expomos um método para executar uma operação em uma lista inteira, por exemplo. Ponto justo nos documentos para usuários avançados. Em caso de dúvida, tente nosso Grupo do Google para obter conversas detalhadas: groups.google.com/forum/#!forum/firebase-talk A equipe é muito ativa aqui!
Rob DiMarco 21/08
1
@RobDiMarco Isso é maravilhoso de ouvir. Eu vi as funções do Firebase ontem e fiquei empolgado o dia inteiro porque achei que o Firebase mudaria o jogo e estava prestes a revolucionar o back-end. Sério, eu poderia ensinar alguém que nunca havia codificado em sua vida a manter um back-end no Firebase. Isso é incrível e assustador. Cheers
Ced
5

Você pode obter os detalhes pelo seguinte código.

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("users");
myRef.orderByChild("name").equalTo("Alex").addListenerForSingleValueEvent(new ValueEventListener() {           
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                        Log.d(TAG, "PARENT: "+ childDataSnapshot.getKey());
                        Log.d(TAG,""+ childDataSnapshot.child("name").getValue()); 
                    }
Nabajyoti Das
fonte
4

Eu acho que a melhor abordagem é definir os IDs dos usuários com base no objeto de autenticação fornecido pelo Firebase. Quando crio meus usuários, faço:

FirebaseRef.child('users').child(id).set(userData);

Esse id vem de:

var ref = new Firebase(FIREBASE);
var auth = $firebaseAuth(ref);
auth.$authWithOAuthPopup("facebook", {scope: permissions}).then(function(authData) {
    var userData = {}; //something that also comes from authData
    Auth.register(authData.uid, userData);
}, function(error) {
    alert(error);
});

Os serviços de autenticação do Firebase sempre garantirão um ID exclusivo entre todos os seus provedores para serem definidos no uid. Dessa forma, você sempre terá o auth.uid e poderá acessar facilmente o usuário desejado para atualizá-lo, como:

FirebaseRef.child('users').child(id).child('name').set('Jon Snow');
diegopso
fonte
2

Esta foi uma paráfrase de uma postagem que me ajudou ao tentar acessar o ID exclusivo gerado automaticamente. Acesse os IDs exclusivos do Firebase na ng-repeat usando a sincronização implícita angularFire

Obrigado, bennlich (fonte):

O Firebase se comporta como um objeto javascript normal. Talvez o exemplo abaixo possa levá-lo ao caminho certo.

<div ng-repeat="(name, user) in users">
    <a href="" ng-href="#/{{name}}">{{user.main}}</a>
</div>

Edit: Não tem 100% de certeza do resultado desejado, mas aqui está um pouco mais que pode desencadear um momento de 'aha'. Clique na tecla que você está tentando acessar diretamente no painel do Firebase. A partir daí, você pode usar algo como:

var ref = new Firebase("https://online-b-cards.firebaseio.com/users/<userId>/name);
    ref.once('value', function(snapshot) {
        $scope.variable= snapshot.val();
});
AnthonyC
fonte
Olá Anthony, obrigado pelas informações sobre a estrutura REST (?) E isso definitivamente afetou um 'aha'. Olhando para trás neste post, fiquei claro agora que eu estruturei meus dados de uma maneira um pouco estranha, obrigado pelas dicas e vou lembrá-lo do meu próximo projeto baseado em firebase!
Richard Bamford
2

Veja como acessar as chaves exclusivas geradas automaticamente no Firebase: estrutura de dados : - OnlineBcards - UniqueKey

database.ref().on("value", function(snapshot) {
      // storing the snapshot.val() in a variable for convenience
      var sv = snapshot.val();
      console.log("sv " + sv); //returns [obj obj]

      // Getting an array of each key in the snapshot object
      var svArr = Object.keys(sv);
      console.log("svArr " + svArr); // [key1, key2, ..., keyn]
      // Console.log name of first key
      console.log(svArr[0].name);
}, function(errorObject) {
  console.log("Errors handled: " + errorObject.code);
});
Juan Reyes
fonte
1

A maneira mais simples é parar de usar o .push(){}

função que irá gerar essa chave aleatória. Mas use a .update(){}função em que você pode especificar o nome da criança em vez de ter a chave aleatória.

Miah Thompson
fonte
1

Recuperando dados:

No seu banco de dados, você está usando um ID aleatório gerado usando o push(), portanto, se desejar recuperar os dados, faça o seguinte:

Usando o Firebase no aplicativo Android:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(new ValueEventListener() {           
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot datas : dataSnapshot.getChildren()) {
                    String name=datas.child("name").getValue().toString();
                }
             }

            @Override
           public void onCancelled(DatabaseError databaseError) {
          }
     });

Usando Firebase em Javascript:

  firebase.database().ref().child("users").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
    var name=childSnapshot.val().name;
  });
});

Aqui você tem o instantâneo (localização dos dados) e, em usersseguida, faz um loop dentro de todos os IDs aleatórios e recupera os nomes.


Recuperando dados para um usuário específico:

Agora, se você deseja recuperar informações apenas para um usuário específico, é necessário adicionar uma consulta:

Usando o Firebase no aplicativo Android:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
Query queries=ref.orderByChild("name").equalTo("Alex");
queries.addListenerForSingleValueEvent(new ValueEventListener() {...}

Usando Firebase com Javascript

firebase.database().ref().child("users").orderByChild("name").equalTo("Alex").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
      var name=childSnapshot.val().name;
   });
});

Usar orderByChild("name").equalTo("Alex")é como dizer, where name="Alex"para recuperar os dados relacionados ao Alex.


Melhor maneira:

O melhor é usar a autenticação do Firebase, gerando um ID exclusivo para cada usuário e usá-lo em vez de um ID aleatório push(). Dessa forma, você não precisa percorrer todos os usuários, pois possui o ID e pode acessá-lo facilmente.

Primeiro, o usuário precisa estar conectado, então você pode recuperar o ID exclusivo e anexar um ouvinte para recuperar os outros dados desse usuário:

Usando o Firebase com Android:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
String uid = FirebaseAuthentication.getInstance().getCurrentUser().getUid();

ref.child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
         public void onDataChange(DataSnapshot dataSnapshot) { 
           String name=dataSnapshot.child("name").getValue().toString(); 
   }
         @Override
       public void onCancelled(DatabaseError databaseError) {
      }
 });

Usando Firebase com Javascript:

    var user = firebase.auth().currentUser;
    var uid=user.uid;

    firebase.database().ref().child("users").child(uid).on('value', function (snapshot) {
     var name=snapshot.val().name;
   });
 
Peter Haddad
fonte
0

A maneira mais simples e melhor de adicionar um ID exclusivo ao seu banco de dados de acordo com o usuário autenticado é:

private FirebaseAuth auth;

String UId=auth.getCurrentUser().getUid();

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users");

User user = new User(name,email,phone,address,dob,bloodgroup);

myRef.child(UId).setValue(user);

A interface do usuário será um ID exclusivo para um email / usuário autenticado específico

M.Usman Younas
fonte
3
Isso não aborda a questão. A questão era como obter e definir dados em contas de usuário específicas. Seu código cria uma conta de usuário e, na verdade, não é válido, pois você não pode .setValue (usuário) porque o usuário não é um parâmetro válido.
31417 Jay