Получение пользователей по свойству имени с помощью Firebase

129

Я пытаюсь создать приложение, в котором я могу получать / устанавливать данные в определенных учетных записях пользователей, и меня соблазнил Firebase.

Проблема, с которой я столкнулся, заключается в том, что я не знаю, как нацелить данные конкретных пользователей, когда моя структура выглядит так:

Моя структура данных описана нижеприведенным текстом.

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

Я огляделся и не могу найти ничего о том, как получить доступ к отдельным данным, не говоря уже о том, что им в качестве идентификатора предоставляется случайный хэш.

Как мне получить информацию об отдельных пользователях на основе их имени? Если есть лучший способ сделать это, пожалуйста, скажите мне!

Ричард Бэмфорд
источник
попробуйте это: stackoverflow.com/questions/32886546/…
ugali soft

Ответы:

156

Раньше Firebase требовала, чтобы вы создавали собственные индексы или загружали все данные в определенном месте для поиска и извлечения элементов, соответствующих некоторому дочернему атрибуту (например, всем пользователям с name === "Alex").

В октябре 2014 года Firebase представила новые функции запросов с помощью этого orderByChild()метода, который позволяет выполнять этот тип запросов быстро и эффективно. См. Обновленный ответ ниже.


При записи данных в Firebase у вас есть несколько разных вариантов, которые будут отражать разные варианты использования. На высоком уровне Firebase представляет собой хранилище данных NoSQL с древовидной структурой и предоставляет несколько простых примитивов для управления списками данных:

  1. Напишите в Firebase уникальный известный ключ:

    ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
    
  2. Добавить в списки с автоматически сгенерированным ключом, который будет автоматически сортировать по написанному времени:

    ref.child('users').push({ "first_name": "rob", "age": 28 })
    
  3. Слушайте изменения в данных по их уникальному известному пути:

    ref.child('users').child('123').on('value', function(snapshot) { ... })
    
  4. Отфильтруйте или упорядочите данные в списке по ключу или значению атрибута :

    // 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', ...)
    

С добавлением orderByChild()вам больше не нужно создавать собственный индекс для запросов по дочерним атрибутам! Например, чтобы получить всех пользователей с именем «Alex»:

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

Здесь инженер Firebase. При записи данных в Firebase у вас есть несколько разных вариантов, которые будут отражать различные варианты использования приложений. Поскольку Firebase - это хранилище данных NoSQL, вам нужно будет либо хранить свои объекты данных с уникальными ключами, чтобы вы могли напрямую обращаться к этому элементу, либо загружать все данные в определенном месте и перебирать каждый элемент, чтобы найти узел, который вы ищете. , См. Раздел « Запись данных и управление списками» для получения дополнительной информации.

Когда вы пишете данные в Firebase, вы можете либо setданные, используя уникальный, определенный путь (т.е. a/b/c), либо pushданные в списке, который будет генерировать уникальный идентификатор (т.е. a/b/<unique-id>) и позволит вам сортировать и запрашивать элементы в этом списке по времени. , Уникальный идентификатор, который вы видите выше, создается путем вызова pushдля добавления элемента в список по адресу online-b-cards/users.

Вместо того, чтобы использовать pushздесь, я бы рекомендовал использовать setи хранить данные для каждого пользователя с использованием уникального ключа, такого как адрес электронной почты пользователя. Затем вы можете получить доступ к данным пользователя напрямую, перейдя online-b-cards/users/<email>через Firebase JS SDK. Например:

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('hello@hello.com')) 
myUser.set({ email: 'hello@hello.com', name: 'Alex', phone: 12912912 });

Обратите внимание: поскольку Firebase не разрешает использование определенных символов в ссылках (см. Создание ссылок ), мы удаляем .и заменяем его на ,в приведенном выше коде.

Роб ДиМарко
источник
1
@RobDiMarco У вас есть ответ на вопрос, поставленный ниже Стивеном?
Чарльз Хан
2
Привет, @RobDiMarco. Хотя ваше предложение использовать адреса электронной почты в качестве основы для идентификатора все еще актуально, возможно, стоит расширить свой ответ, чтобы указать на новую orderByChildфункцию. Учитывая, что этот ответ довольно часто появляется как релевантный / связанный ответ, люди обязательно смотрят на него и должны знать о новых функциях запроса.
Франк ван Пуффелен
1
@FrankvanPuffelen Отличная идея - спасибо за заметку. Я обновлю это сегодня.
Роб ДиМарко
1
@Ced К сожалению, я не могу комментировать то, что находится в разработке. Я обещаю, что мы усердно работаем (это всегда было правдой), но не могу сообщить подробностей. API базы данных действительно имеет некоторые ограничения, и мы делаем это намеренно, чтобы предоставлять только те методы, для которых мы можем гарантировать определенный уровень производительности. Вот почему мы не предоставляем метод, например, для запуска операции над всем списком. Справедливый пункт в документации для продвинутых пользователей. Если сомневаетесь, попробуйте нашу группу Google для подробного обсуждения: groups.google.com/forum/#!forum/firebase-talk Здесь очень активна команда!
Роб ДиМарко
1
@RobDiMarco Приятно слышать. Вчера я увидел функции Firebase и весь день был в восторге, потому что думал, что Firebase изменит правила игры и собирается произвести революцию в серверной части. Серьезно, я мог бы научить того, кто никогда в жизни не программировал, поддерживать серверную часть на Firebase. Это довольно удивительно и довольно страшно. Cheers
Ced
5

Вы можете получить подробности с помощью следующего кода.

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()); 
                    }
Набаджьоти Дас
источник
4

Я думаю, что лучший подход - определить идентификаторы пользователей на основе объекта аутентификации, предоставленного Firebase. Когда я создаю своих пользователей, я делаю:

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

Этот идентификатор происходит от:

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

Сервисы аутентификации Firebase всегда гарантируют, что уникальный идентификатор среди всех своих провайдеров будет установлен на uid. Таким образом, у вас всегда будет auth.uid, и вы сможете легко получить доступ к желаемому пользователю для его обновления, например:

FirebaseRef.child('users').child(id).child('name').set('Jon Snow');
diegopso
источник
2

Это был перефразирование сообщения, которое помогло мне при попытке получить доступ к автоматически сгенерированному уникальному идентификатору. Доступ к уникальным идентификаторам Firebase в ng-repeat с использованием неявной синхронизации angularFire

Спасибо, Беннлих (источник):

Firebase ведет себя как обычный объект javascript. Возможно, приведенный ниже пример поможет вам встать на верный путь.

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

Изменить: не уверен на 100% в желаемом результате, но вот еще кое-что, что может вызвать момент «ага». Нажмите на ключ, к которому вы пытаетесь получить доступ, прямо на панели управления Firebase. Оттуда вы можете использовать что-то вроде:

var ref = new Firebase("https://online-b-cards.firebaseio.com/users/<userId>/name);
    ref.once('value', function(snapshot) {
        $scope.variable= snapshot.val();
});
AnthonyC
источник
Привет, Энтони, спасибо за информацию, касающуюся структуры REST (?), И это определенно вызвало «ага». Оглядываясь назад на этот пост, теперь мне становится ясно, что я структурировал свои данные немного неудобным образом, спасибо за советы, и я учту их в своем следующем проекте на основе Firebase!
Ричард Бэмфорд
2

Вот как получить доступ к автоматически сгенерированным уникальным ключам в Firebase: структура данных : - 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);
});
Хуан Рейес
источник
1

Самый простой способ - прекратить использование .push(){}

функция, которая будет генерировать этот случайный ключ. Но вместо этого используйте .update(){}функцию, в которой вы можете указать имя дочернего элемента вместо случайного ключа.

Миа Томпсон
источник
1

Извлечение данных:

В своей базе данных вы используете случайный идентификатор, который создается с помощью push(), поэтому, если вы хотите получить данные, выполните следующие действия:

Использование Firebase в приложении для 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) {
          }
     });

Использование Firebase в Javascript:

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

Здесь у вас есть моментальный снимок (расположение данных), usersзатем вы перебираете все случайные идентификаторы и извлекаете имена.


Получение данных для конкретного пользователя:

Теперь, если вы хотите получить информацию только для определенного пользователя, вам нужно добавить запрос:

Использование Firebase в приложении для Android:

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

Использование Firebase с Javascript

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

Использование orderByChild("name").equalTo("Alex")- это все равно что сказать, where name="Alex"что он получит данные, связанные с Алексом.


Лучший способ:

Лучше всего использовать Firebase Authentication, тем самым генерируя уникальный идентификатор для каждого пользователя и используя его вместо случайного идентификатора push(), таким образом вам не нужно перебирать всех пользователей, поскольку у вас есть идентификатор и вы можете легко получить к нему доступ.

Во-первых, пользователь должен войти в систему, затем вы можете получить уникальный идентификатор и подключить слушателя для получения других данных этого пользователя:

Использование Firebase с 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) {
      }
 });

Использование Firebase с 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;
   });
 
Питер Хаддад
источник
0

Самый простой и лучший способ добавить уникальный идентификатор в базу данных ur в соответствии с аутентифицированным пользователем:

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

UId будет уникальным идентификатором для определенного аутентифицированного адреса электронной почты / пользователя.

М.Усман Юнас
источник
3
Это не решает вопрос. Вопрос был в том, как получить и установить данные в конкретных учетных записях пользователей. Ваш код создает учетную запись пользователя и на самом деле недействителен, так как вы не можете .setValue (user), потому что user не является допустимым параметром.
Джей