Obtener usuarios por nombre de propiedad usando Firebase

129

Estoy tratando de crear una aplicación donde pueda obtener / configurar datos en cuentas de usuarios específicos y Firebase me tentó.

El problema que tengo es que no sé cómo dirigir datos de usuarios específicos cuando mi estructura se ve así:

Mi estructura de datos se describe en el texto a continuación.

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

He mirado a mi alrededor y realmente no puedo encontrar nada sobre cómo acceder a datos individuales y mucho menos cuando se les da un hash aleatorio como ID.

¿Cómo haría para obtener información de usuarios individuales basada en su nombre? Si hay una mejor manera de hacerlo, ¡dímelo!

Richard Bamford
fuente
intente esto: stackoverflow.com/questions/32886546/…
ugali soft

Respuestas:

156

Anteriormente, Firebase requería que generara sus propios índices o descargara todos los datos en una ubicación para encontrar y recuperar elementos que coincidieran con algún atributo secundario (por ejemplo, todos los usuarios con name === "Alex").

En octubre de 2014, Firebase lanzó una nueva funcionalidad de consulta a través del orderByChild()método, que le permite hacer este tipo de consulta de manera rápida y eficiente. Vea la respuesta actualizada a continuación.


Al escribir datos en Firebase, tiene algunas opciones diferentes que reflejarán diferentes casos de uso. En un alto nivel, Firebase es un almacén de datos NoSQL estructurado en árbol, y proporciona algunas primitivas simples para administrar listas de datos:

  1. Escriba en Firebase con una clave única y conocida:

    ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
    
  2. Agregue a las listas con una clave generada automáticamente que se ordenará automáticamente por hora escrita:

    ref.child('users').push({ "first_name": "rob", "age": 28 })
    
  3. Escuche los cambios en los datos por su ruta única y conocida:

    ref.child('users').child('123').on('value', function(snapshot) { ... })
    
  4. Filtre u ordene datos en una lista por clave o valor de 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', ...)
    

¡Con la adición de orderByChild(), ya no necesita crear su propio índice para consultas sobre atributos secundarios! Por ejemplo, para recuperar todos los usuarios con el nombre "Alex":

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

Ingeniero en Firebase aquí. Al escribir datos en Firebase, tiene algunas opciones diferentes que reflejarán diferentes casos de uso de aplicaciones. Dado que Firebase es un almacén de datos NoSQL, deberá almacenar sus objetos de datos con claves únicas para que pueda acceder directamente a ese elemento o cargar todos los datos en una ubicación particular y recorrer cada elemento para encontrar el nodo que está buscando . Consulte Escribir datos y administrar listas para obtener más información.

Cuando escribe datos en Firebase, puede setusar datos utilizando una ruta única y definida (es decir a/b/c), o pushdatos en una lista, lo que generará una identificación única (es decir a/b/<unique-id>) y le permitirá ordenar y consultar los elementos de esa lista por tiempo . La identificación única que está viendo arriba se genera al llamar pushpara agregar un elemento a la lista en online-b-cards/users.

En lugar de usar pushaquí, recomendaría usar sety almacenar los datos de cada usuario con una clave única, como la dirección de correo electrónico del usuario. Luego puede acceder a los datos del usuario directamente navegando a online-b-cards/users/<email>través de Firebase JS SDK. Por ejemplo:

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 });

Tenga en cuenta que, dado que Firebase no permite ciertos caracteres en las referencias (consulte Creación de referencias ), eliminamos .y reemplazamos con a ,en el código anterior.

Rob DiMarco
fuente
1
@RobDiMarco ¿Tiene una respuesta para la pregunta publicada por Stephen a continuación?
Charles Han el
2
Hola @RobDiMarco. Si bien su sugerencia de usar direcciones de correo electrónico como base para la identificación sigue siendo válida, podría valer la pena ampliar su respuesta para señalar la nueva orderByChildfunción. Dado que esta respuesta aparece con bastante frecuencia como una respuesta relevante / relacionada, es probable que las personas la vean y deben conocer las nuevas funciones de consulta.
Frank van Puffelen
1
@FrankvanPuffelen Gran idea: gracias por la nota. Lo actualizaré hoy.
Rob DiMarco
1
@Ced Desafortunadamente, no puedo comentar sobre lo que está en proceso. Prometo que estamos trabajando duro (eso siempre ha sido cierto), pero no puedo dar detalles. La API de base de datos es de hecho restrictiva en algunos aspectos, y hacemos esto deliberadamente para exponer solo métodos para los que podemos garantizar ciertos niveles de rendimiento. Es por eso que no exponemos un método para ejecutar una operación en una lista completa, por ejemplo. Punto justo en los documentos para usuarios avanzados. En caso de duda, pruebe nuestro Grupo de Google para conversaciones detalladas: groups.google.com/forum/#!forum/firebase-talk ¡ El equipo está muy activo aquí!
Rob DiMarco
1
@RobDiMarco Es maravilloso escuchar eso. Ayer vi las funciones de Firebase, y me exageraron todo el día porque pensé que Firebase era un cambio de juego y estaba a punto de revolucionar el back-end. En serio, podría enseñarle a alguien que nunca ha codificado en su vida a mantener un backend en Firebase. Eso es bastante sorprendente y bastante aterrador. Saludos
Ced
5

Puede obtener los detalles por el siguiente 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
fuente
4

Creo que el mejor enfoque es definir los identificadores de los usuarios basados ​​en el objeto de autenticación proporcionado por Firebase. Cuando creo mis usuarios, hago:

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

Esta identificación proviene 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);
});

Los servicios de autenticación de Firebase siempre asegurarán una identificación única entre todos sus proveedores que se establecerá en uid. De esta manera siempre tendrá el auth.uid y podrá acceder fácilmente al usuario deseado para actualizarlo, como:

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

Esta fue una paráfrasis de una publicación que me ayudó al intentar acceder a la identificación única generada automáticamente. Acceda a identificadores únicos de Firebase dentro de ng-repeat usando la sincronización implícita angularFire

Gracias, bennlich (fuente):

Firebase se comporta como un objeto javascript normal. Quizás el ejemplo a continuación pueda llevarlo por el camino correcto.

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

Editar: No estoy 100% seguro de su resultado deseado, pero aquí hay un poco más que podría provocar un momento 'aha'. Haz clic en la tecla a la que intentas acceder directamente en el panel de Firebase. Desde allí puedes 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
fuente
Hola Anthony, gracias por la información sobre la estructura REST (?) Y definitivamente dio un 'aha'. Mirando hacia atrás en esta publicación, me quedó claro ahora que había estructurado mis datos de una manera un poco incómoda, gracias por los consejos y lo tendré en cuenta para mi próximo proyecto basado en Firebase.
Richard Bamford el
2

Así es como acceder a las claves únicas generadas automáticamente en Firebase: estructura de datos : - 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
fuente
1

La forma más sencilla es dejar de usar el .push(){}

función que generará esa clave aleatoria. Pero en su lugar, use la .update(){}función donde puede especificar el nombre del niño en lugar de tener la clave aleatoria.

Miah Thompson
fuente
1

Recuperando datos:

En su base de datos, está utilizando una identificación aleatoria que se genera utilizando push(), por lo tanto, si desea recuperar los datos, haga lo siguiente:

Usando Firebase en la aplicación de 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 en Javascript:

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

Aquí tiene la instantánea (ubicación de los datos) y usersluego realiza un bucle dentro de todos los identificadores aleatorios y recupera los nombres.


Recuperación de datos para un usuario específico:

Ahora, si desea recuperar información solo para un usuario específico, debe agregar una consulta:

Usando Firebase en la aplicación de Android:

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

Usando Firebase con 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")es como decir where name="Alex"que recuperará los datos relacionados con Alex.


Mejor manera:

Lo mejor es usar Firebase Authentication, generando así una identificación única para cada usuario y usándola en lugar de una identificación aleatoria push(), de esta manera no tiene que recorrer todos los usuarios ya que tiene la identificación y puede acceder fácilmente a ella.

Primero, el usuario debe iniciar sesión, luego puede recuperar la identificación única y adjuntar un oyente para recuperar los otros datos de ese usuario:

Usando Firebase con 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 con 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
fuente
0

La manera más simple y mejor de agregar una identificación única a su base de datos según el usuario autenticado es esta:

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);

El UId será un ID único para un usuario / correo electrónico autenticado específico

M.Usman Younas
fuente
3
Eso no responde a la pregunta. La pregunta era cómo obtener y establecer datos en cuentas de usuario específicas. Su código crea una cuenta de usuario y en realidad no es válido ya que no puede .setValue (usuario) porque el usuario no es un parámetro válido.
Jay