Infinit l oop с огненной базой и angular - PullRequest
0 голосов
/ 06 апреля 2020

У меня проблема с бесконечным l oop при сохранении моих данных в базе данных с this.db.collection('users').doc(this.useruid).update({Info: this.currentInfo})

private currentInfo:string[];
private useruid: string;
...
constructor(private AngularAuth: AngularFireAuth,
    private db:AngularFirestore) { }

...

sendInfo(text:string){
    this.useruid = this.AngularAuth.auth.currentUser.uid;
    this.db.collection('users').doc(this.useruid).snapshotChanges().subscribe(a=>{
      const data = a.payload.data() as {name:string, Info:string[]};
      data.Info.forEach(element => {
        this.currentInfo.push(element);
      });
      this.currentInfo.push(text);
      this.db.collection('users').doc(this.useruid).update({
        Info: this.currentInfo
      })...
    })
}

В качестве примера представьте, что в настоящее время у меня есть currentInfo = ["a","b","c"] и text = "d", после того, как вы запустите метод sendInfo( ), я получу все oop с: ["a","b","c","d","a","b","c","d","d","a","b","c","d","a","b","c","d","d","d"...] и т. д.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Вы можете использовать pipe и сначала получить нужные значения, а затем снова обновить.

sendInfo(text: string) {
    this.useruid = this.AngularAuth.auth.currentUser.uid;
    this.db.collection('users').doc(this.useruid).valueChanges().pipe(first()).subscribe(a => {
        const data = a.payload.data() as {name:string, Info:string[]};
        data.Info.forEach(element => {
            this.currentInfo.push(element);
        });
        this.currentInfo.push(text);
    }
    this.db.collection('users').doc(this.useruid).update({
        Info: this.currentInfo
    })
}

Первый метод rx js используется для получения первого значения, испускаемого наблюдаемой. После этого отписывается от наблюдаемого.

0 голосов
/ 06 апреля 2020

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

var userDocRef = collection('users').doc(this.useruid);

return db.runTransaction(function(transaction) {
    // This code may get re-run multiple times if there are conflicts.
    return transaction.get(userDocRef).then(function(userDoc) {
        if (!userDoc.exists) {
            throw "Document does not exist!";
        }

        const data = userDoc.data() as {name:string, Info:string[]};
        data.Info.forEach(element => {
          this.currentInfo.push(element);
        });
        this.currentInfo.push(text);

        transaction.update(userDocRef, { Info: this.currentInfo });
    });
}).then(function() {
    console.log("Transaction successfully committed!");
}).catch(function(error) {
    console.log("Transaction failed: ", error);
});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...