Вызов функции затем после извлечения данных из firebase в ionic 3 - PullRequest
0 голосов
/ 08 ноября 2018

Я хочу получить данные из firebase, после чего я хочу выполнить другую функцию. Вторая функция должна ждать, пока первая не будет завершена.

this.oAngularFireDatabase.database.ref('Users').orderByKey()
            .on('value', snapshot => {
              if (snapshot.hasChildren()) {
                snapshot.forEach(innerSnap => {
                  if (innerSnap.hasChild(user.uid)) {
                    //User role key
                    this.loggedInUserUserRoleKey = innerSnap.key;
                    //User id
                    this.loggedInUserId = user.uid;

                    //User name
                    this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();

                    if (innerSnap.child(user.uid).hasChild("user_image")) {
                      //User Image
                      this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
                    }
                    return false;
                  }
                })
              }
            }) 

Я не могу вызвать then функцию после on, это выдает ошибку. В приведенном выше коде я хочу вызвать другую функцию после того, как все данные получены из firebase.

1 Ответ

0 голосов
/ 08 ноября 2018

Метод Firebase on() может запускаться несколько раз: один раз при первоначальной загрузке данных и снова при каждом изменении данных. Поскольку обещание (то, что вы называете then() на) может быть выполнено только один раз, on() не может вернуть обещание.

Здесь есть два варианта:

  1. Вы хотите загрузить данные только один раз.

    Если это так, вы должны использовать метод once() Firebase, который возвращает обещание.

    this.oAngularFireDatabase.database.ref('Users').orderByKey()
        .once('value').then(snapshot => {
          if (snapshot.hasChildren()) {
            snapshot.forEach(innerSnap => {
              if (innerSnap.hasChild(user.uid)) {
                //User role key
                this.loggedInUserUserRoleKey = innerSnap.key;
                //User id
                this.loggedInUserId = user.uid;
    
                //User name
                this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();
    
                if (innerSnap.child(user.uid).hasChild("user_image")) {
                  //User Image
                  this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
                }
                return false;
              }
            })
          }
        }).then(value => {
            // TODO: perform subsequent action on boolean value
        })
    
  2. Вы также хотите прослушать изменения данных.

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

    this.oAngularFireDatabase.database.ref('Users').orderByKey()
        .on('value', snapshot => {
          if (snapshot.hasChildren()) {
            snapshot.forEach(innerSnap => {
              if (innerSnap.hasChild(user.uid)) {
                //User role key
                this.loggedInUserUserRoleKey = innerSnap.key;
                //User id
                this.loggedInUserId = user.uid;
    
                //User name
                this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();
    
                if (innerSnap.child(user.uid).hasChild("user_image")) {
                  //User Image
                  this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
                }
              }
            })
            // TODO: perform subsequent action on data
          }
        }) 
    

Обратите внимание, что обе эти операции выглядят довольно дорого для того, что они пытаются выполнить: сканирование дерева JSON на предмет определенного значения является анти-паттерном в Firebase и, как правило, означает, что вы должны изменить / дополнить свой JSON, чтобы разрешить прямой поиск или запрос.

Например, я подозреваю, что у вас сейчас есть структура типа /Users/$randomkey/$uid: { ..user data... }. Для повышения производительности рассмотрите возможность хранения пользовательских данных непосредственно под их UID: /Users/$uid: { ..user data... }. Это устраняет необходимость запроса и позволяет напрямую загружать данные для пользователя из this.oAngularFireDatabase.database.ref('Users').child(user.uid).

...