带Firebase和角度的无限循环

时间:2020-04-06 18:45:13

标签: javascript angular firebase google-cloud-firestore angularfire2

我遇到无限循环问题,使用 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( )之后, 我遇到了一个循环:["a","b","c","d","a","b","c","d","d","a","b","c","d","a","b","c","d","d","d"...],依此类推。

2 个答案:

答案 0 :(得分:0)

要基于文档的当前值use a transaction更新

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

除了防止您当前遇到的无限循环外,这还可以防止多个用户几乎想要同时更新文档时覆盖彼此的结果。

答案 1 :(得分:0)

您可以先使用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
    })
}

rxjs的第一个方法用于获取可观察对象发出的第一个值。之后,它取消了可观察对象的订阅。

相关问题