Firebase数据库事务搜索和更新 [英] Firebase database transactional search and update

查看:43
本文介绍了Firebase数据库事务搜索和更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在firebase实时数据库中有一个集合,该集合是可以在每个商店"中使用一次的代码池.我需要搜索未使用的代码,然后以原子方式将其标记为由商店保留.问题是我不知道如何在firebase中进行事务搜索和更新,并且未使用的代码被使用"多次,直到更新为止.

I have a collection in firebase real time database that is a pool of codes that can be used once per 'store'. I need to search for an unused code, then mark it reserved by a store in an atomic fashion. The problem is I can't figure out how to do a transactional search and update in firebase, and the unused code is being 'used' multiple times until it gets updated.

const getUnusedCode = (storeID) => {
  const codeRef = rtdb.ref('codes');

 return codeRef
    .orderByChild(storeID)
    .equalTo(null)
    .limitToFirst(1)
    .once('child_added')
    .then(snap => {
     //setting the map {[storeID]:true} reserves the code
     return snap.ref.update({ [storeID]: true }).then(() => {
        return snap.key;
      });
    });
};

这是代码"集合的结构:

Here is the structure of the 'codes' collection:

{
  "-LQl9FFD39PAeN5DnrGE" : {
    "code" : 689343821901,
    "i" : 0,
    "5s6EgdItKW7pBIawgulg":true,
    "ZK0lFbDnXcWJ6Gblg0tV":true,
    "uKbwxPbZu2fJlsn998vm":true
  },
  "-LQl9FOxT4eq6EbwrwOx" : {
    "code" : 689343821918,
    "i" : 1,
    "5s6EgdItKW7pBIawgulg":true
  },
  "-LQl9FPaUV33fvkiFtv-" : {
    "code" : 689343821925,
    "i" : 2
  },
  "-LQl9FQEwKKO9T0z4LIP" : {
    "code" : 689343821932,
    "i" : 3,
    "ZK0lFbDnXcWJ6Gblg0tV":true
  },
  "-LQl9FQsEVSNZyhgdHmI" : {
    "code" : 689343821949,
    "i" : 4,
    "5s6EgdItKW7pBIawgulg":true,
    "uKbwxPbZu2fJlsn998vm":true
  }
}

在此数据中,"5s6EgdItKW7pBIawgulg"是商店ID,为true表示此代码已用于该商店

In this data, "5s6EgdItKW7pBIawgulg" is a store id, and true means this code has been used for this store

当导入新项目时,此函数可能每分钟被调用数百次,并且由于不是原子搜索然后更新,因此会返回重复项.在Firebase中有可能吗?

When new items are being imported, this function may get called hundres of times a minute, and is returning duplicates since it's not an atomic search-then-update. Is this possible in Firebase?

推荐答案

据我了解,您具有这样的结构

From what I understand you have a structure like this

codes: {
  "code1": {
    storeid: "store1"
  },
  "code2": {
    storeid: "store2"
  }
}

您正在尝试按商店进行交易更新.

And you're trying to transactionally update it per store.

如果这是您要执行的唯一更新,强烈建议您反转数据结构:

If this is the only update you're trying to do, I'd highly recommend inverting your data structure:

codes: {
  "store1": "code1",
  "store2": "code2"
}

在这种结构下,商店的交易非常简单,因为路径是已知的:

On this structure the transaction for a store is quite simple, since the path is known:

var storeRef = firebase.database().ref("codes").child("store1");
storeRef.transation(function(current) {
  if (current) {
    // remove the code from the database
    return null;
  }
  else {
    // abort the transaction, since the code no longer exists
    return undefined;
  }
});

如果您无法更改数据结构,我可能会使用您当前的代码来找到该代码的 DatabaseReference ,然后在回调中使用事务进行更新:

If you can't change the data structure, I'd probably user your current code to find the DatabaseReference to the code, and then use a transaction within the callback to update:

codeRef
    .orderByChild(storeID)
    .equalTo(null)
    .limitToFirst(1)
    .once('child_added')
    .then(snap => {
      //setting the map {[storeID]:true} reserves the code
      return snap.ref.transaction(function(current) {
        if (!current || current[storeId]) {
          // the node no longer exists, or it already was claimed for this store
          return undefined; // abort the transaction
        }
        else {
          current[storeId] = true;
          return current;
        }
      })
    });

这篇关于Firebase数据库事务搜索和更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆