仅允许在Firestore中创建一个文档,禁止更新,编辑等

时间:2019-05-06 18:01:55

标签: firebase vuejs2 google-cloud-firestore firebase-security-rules

我正在使用VueJS和Firebase Firestore编写各种Quiz应用程序。

到目前为止,除了最后一部分,我已经完成了所有工作。

允许用户无需登录即可回答问题。

在最后阶段,还有最后一个问题。每个人都可以回答这个问题,但是我需要能够发现谁是第一人。

到目前为止,我已经尝试检查答案是否为空,这是可行的,但是响应时间是问题所在,我可以轻松地重现两个或多个同时回答的用户,并告知他们获胜者。

我当前正在尝试交易,但是无法弄清楚如果文档已经存在,该如何捕捉。这是示例代码:

let vm = this;
fsdb.runTransaction(function (transaction) {
    let voteDocRef = fsdb.collection('final_vote').doc('vote');
    return transaction.get(voteDocRef).then(function (voteDoc) {
        if (!voteDoc.exists) {
            voteDocRef.set({voted: true}).then(function () {
                vm.trueAnswer(index);
                return 'set executed!';
            }).catch(function () {
                vm.falseAnswer(index);
                throw 'Someone already voted!';
            });
            return 'Document created!';
        } else {
            throw 'Someone already voted!';
        }
    });

vm.trueAnswer和vm.falseAnswer是我用来显示弹出消息的方法。

这是用户提交答案后触发的方法。

起初,我尝试了每个人都可以读取,编写...的规则,但是现在我试图仅在文档不存在的情况下限制写入。这是当前的规则集:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }

    match /{collectionName}/{docId} {
      allow create: if collectionName == 'final_vote' && docId == 'vote';
    }
  }
}

到目前为止,这无法按预期进行。

关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

您会尝试以下代码吗?

//select specific product whose Id is 1 
var product = await _context.Products.Include(p => p.ProductCategories)
                                              .ThenInclude(pc => pc.Category)
                                              .FirstOrDefaultAsync(p => p.Id == 1);


var categories = product.ProductCategories.Select(pc => pc.Category).ToList();
let vm = this;
fsdb.runTransaction(function (transaction) {
    let voteDocRef = fsdb.collection('final_vote').doc('vote');
    return transaction.get(voteDocRef).then(function (voteDoc) {
        if (voteDoc.data().voted !== true) {
            voteDocRef.set({voted: true}).then(function () {
                vm.trueAnswer(index);
                return 'set executed!';
            }).catch(function () {
                vm.falseAnswer(index);
                throw 'Someone already voted!';
            });
            return 'Document created!';
        } else {
            throw 'Someone already voted!';
        }
    });

我认为service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } match /final_vote/{docId} { allow create, update: if true; } } } 优于final_votes作为集合名称。