Как получить данные один раз из firebase по идентификатору - PullRequest
0 голосов
/ 16 февраля 2020

Здравствуйте, я пытаюсь получить электронную почту пользователя каждого сообщения. (Каждое сообщение (чат) имеет идентификатор пользователя). Я получаю все пользовательские данные через getUser на * ngIf. А потом просто покажи письмо. Это работает, и на сайте нет повторения данных, но вкладка скоро зависнет, если я не остановлюсь с отладчиком. Я не знаю почему, но это бесконечно l oop. Это выглядит так: https://i.imgur.com/XBku0uc.png Создает тысячи журналов консоли.

Это getUser:

  getUser(uid:string){
    this.userCollection = this.db.collection('users', ref => ref.where('uid', '==', uid));
    this.userCollection.valueChanges().subscribe(queriedItems => {
      this.userDT=new Usermodel(queriedItems[0].uid,queriedItems[0].email,queriedItems[0].displayName,queriedItems[0].photoURL,queriedItems[0].emailVerified);
    });
    console.log(this.userDT.email)
    return this.userDT;
  }

, и я получаю данные в HTML прямой вызов:

<div class="msg_container_other" *ngIf="getUser(chat.uid); let otherUser">
                  {{chat.content}}
                  <span class="msg_time"><i class="fas fa-check-double" style="color: #292929;"></i> {{otherUser.email}}. {{ chat.date | date:'d/M/y H:mm'}}</span>
</div> 

Если вам нужно узнать, что такое чаты: https://i.imgur.com/iThi424.png и более контекст html: https://i.imgur.com/GRupLAp.png

Я несколько дней пробовал что-то и не знаю, что еще попробовать. Если я удаляю подписку getUser следующим образом:

  getUser(uid:string){
    this.userCollection = this.db.collection('users', ref => ref.where('uid', '==', uid));

    console.log(this.userDT.email)
    return this.userDT;
  }

Тогда она не зацикливается, но, конечно, тогда не может получить данные.

Люди сказали мне, что это не так хороший способ получить данные один раз, потому что я подписываюсь, поэтому я попробовал этот способ, но эффект тот же бесконечный l oop.

    getUser(uid:string){


    this.userCollection = this.db.collection('users', ref => ref.where('uid', '==', uid));
    this.userCollection.get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data().email);
            return doc.data().email;
        });
    })
    .catch(function(error) {
        console.log("Error getting documents: ", error);
    });
}

Этот getUser не работает, либо он делает бесконечным l oop: / не могу поверить, я не могу найти, как получить отдельные данные по запросу

     return this.db.collection('users', ref => ref.where('uid', '==', uid)).snapshotChanges().subscribe(data => {
    return data.map(e => {
      return {
        id: e.payload.doc.id,
        ...e.payload.doc.data()
      } as User;
    })
  }); 

РЕДАКТИРОВАТЬ:

Хорошо, я думаю, что я пытался сделать это лучше, вот как Я go через чаты сейчас: https://i.imgur.com/oJAJDGA.png

   db.collection('chats', ref => ref.where('groupId', '==', this.pathId).orderBy('date')).snapshotChanges().subscribe(data => {
  this.chatsList = data.map(e => {
    return {
      id: e.payload.doc.id,
      ...e.payload.doc.data()
    } as Chat;
  })
});

И это html с новым изменением:

    <div class="card" *ngIf="authService.userData as user">

        <div id="card-box" class="card-box msg_head" ><!--  #scrollMe [scrollTop]="scrollMe.scrollHeight" DA ERROR  -->

            <div id="card-body" class="card-body msg_card_body">
              <div *ngFor="let chat of chatsList">

Все еще могу ' сделать так, чтобы получить пользовательские данные по идентификатору пользователя из идентификатора чата безгранично. l oop tho

EDIT2: Хорошо, я думаю, я лучше понимаю, как работает асинхронная вещь, и я пытался построить Франкенштейн, я обновлю это когда я создаю его по-другому.

EDIT3: Хорошо, я исправил это, получив все асинхронно (как это должен быть) и делает JOIN:

getPages(){ 
  const item: AngularFirestoreCollection = this.afs.collection(`pages`, (ref) => ref.orderBy('createdAt', 'desc'));
  return item.valueChanges().pipe( 
  switchMap(arr => { 
   const userObservable = arr.map(user => this._afs.doc(`users/${user.uid}`) .valueChanges().pipe(first()) );
   return combineLatest(...userObservable) .pipe( map((...users) => { 
      arr.forEach((author, index) => { 
       author['author_avatar'] = users[0][index]['photoURL']; 
       author['author_username'] = users[0][index]['displayName']; 
      });
      return arr;
      })
      );
    })
    );
   } 

Ответы [ 3 ]

0 голосов
/ 16 февраля 2020

измените ваш метод, чтобы вернуть обещание / наблюдаемый элемент, а не хранить на this. как здесь

getUser(uid:string){
  return this.firestore
    .collection('users')
    .valueChanges({ idField: uid });
}
and in the template
*ngIf="getUser() | async as otherUser"
0 голосов
/ 16 февраля 2020

Хорошо, я исправил это, получив все асинхронно (как и должно быть) и выполнив JOIN

getPages(){ 
      const item: AngularFirestoreCollection = this.afs.collection(`pages`, (ref) => ref.orderBy('createdAt', 'desc'));
      return item.valueChanges().pipe( 
      switchMap(arr => { 
       const userObservable = arr.map(user => this._afs.doc(`users/${user.uid}`) .valueChanges().pipe(first()) );
       return combineLatest(...userObservable) .pipe( map((...users) => { 
          arr.forEach((author, index) => { 
           author['author_avatar'] = users[0][index]['photoURL']; 
           author['author_username'] = users[0][index]['displayName']; 
          });
          return arr;
          })
          );
        })
        );
       } 
0 голосов
/ 16 февраля 2020

, если вы хотите просто заставить его работать, попробуйте любую из ваших getUser(id) реализаций, но вместо того, чтобы связывать его с функцией в шаблоне - вызовите его в ngOnInit и вместо этого свяжите возвращаемый результат.

ngOnInit() {
  this.getUser(someId);
}
....
*ngIf="userDT"

но на самом деле у вас есть проблемы с пониманием js асинхронных концепций и того, как справляться с такими ситуациями, и простой ответ stackoverflow не поможет лучше понять его

...