【问题标题】:Firebase Data Collection with Unique Member具有唯一成员的 Firebase 数据收集
【发布时间】:2017-04-01 14:08:27
【问题描述】:

我想展示一份玩具清单。 每个玩具都是唯一的名称。 名称可以包含任何字符,因此可以包含点、斜线或美元。 这就是为什么我更喜欢使用 push 方法来获取生成的密钥。

我最终得到的代码很麻烦。 它不是线程安全的,我最终可能会得到重复的玩具。 有没有更好的办法?

var child = testsRef.orderByChild("name").equalTo("Meccano");

return child.once('value').then(function(snapshot) {
  var snap = snapshot.val();
  if (snapshot.val()) {
    alert('Toy ' + value + ' already exists.');
  } else {
    var newPostKey = testsRef.push().key;
    var updates = {};
    updates[newPostKey] = {          name: value        };
    var result = testsRef.update(updates);
    alert('We can only assume that it has worked.' + result);
  }
});

我构建了一个完整的工作代码笔来说明我的问题: http://codepen.io/paganaye/pen/EWrayY

【问题讨论】:

    标签: javascript firebase firebase-realtime-database unique-index


    【解决方案1】:

    使用玩具名称作为密钥,但首先通过 firebase 密钥清理程序运行它,例如:

    function fbKeySanitizer(str) {
      return encodeURIComponent(str).replace(/[.$[\]#\/]/g, function (c) {
        return '%' + c.charCodeAt(0).toString(16).toUpperCase();
      });
    }
    

    您可以像使用 push() 方法一样将原始名称保存为属性,也可以使用 decodeURIComponent() 反转编码以返回完全相同的字符串。

    【讨论】:

    • 我听到你说的话。不过,您的函数确实替换了太多字符。怎么样:函数 fbKeySanitizer(str) { return str.replace(/[%.$[]#\/]/g, function (c) { return '%' + c.charCodeAt(0).toString(16)。 toUpperCase(); }); }
    • 这可能会起作用,但至少在我的情况下,URL 安全是很方便的。选择编码后,请坚持使用。如果您以不同的方式开始编码,即使它们是无损往返,查找也会失败。
    • 我认为您的正则表达式已损坏,您需要在第一个右方括号上进行转义。 "%.$[]#/".replace(/[%.$[]#\/]/g,'*') => "%.$[]#/""%.$[]#/".replace(/[%.$[\]#\/]/g,'*') => "*******"
    • 谢谢。不过,我确实在括号前加上了斜线。看起来评论编辑器把它去掉了。 For the record I ended up with thisfunction fbKeySanitizer(str) { return str.replace(/[%.$[\]#\/]/g, function (c) { return '%' + c.charCodeAt(0).toString(16).toUpperCase(); }); }
    【解决方案2】:

    这是使用 Unicode 字符的替代解决方案。 例如,# 字符被替换为非常相似的等号并倾斜平行:'⧣'。

    var nameElt = document.getElementById("name");
    var sanitizedElt = document.getElementById("sanitized");
    var sanitized2Elt = document.getElementById("sanitized2");
    var decodedElt = document.getElementById("decoded");
    var outpuElt = document.getElementById("output");
    var decoded2Elt = document.getElementById("decoded2");
    
    
    function fbKeySanitizer(str) {
      return str.replace(/[%.$[\]#\/]/g, function (c) {
        return '%' + c.charCodeAt(0).toString(16).toUpperCase();
      });
    }
    
    var unicodeReplacements = {
      '.':'․', // One dot leader
      '$':'ᙚ', // Canadian syllabics carrier: sh
      '[':'⟦', // Mathematical left white square bracket
      ']':'⟧', // Mathematical right white square bracket
      '#':'⧣', // Equals sign and slanted parallel 
      '/':'⧸' // big solidus
    }
    var decodeUnicodeReplacements = {};
    for (var prop in unicodeReplacements) {
      decodeUnicodeReplacements[unicodeReplacements[prop]]=prop;
    }
    
    function fbKeySanitizer2(str) {
      return str.replace(/[.$[\]#\/]/g, function (c) {
        return unicodeReplacements[c];
      });  
    }
    
    function fbDecoded2(str) {
      return str.replace(/[․ᙚ⟦⟧⧣⧸]/g, function (c) {
        return decodeUnicodeReplacements[c];
      });  
    }
    
    function nameKeyUp() {
      var sanitized1string = fbKeySanitizer(nameElt.value);
      sanitizedElt.innerText = sanitized1string;
      decodedElt.innerText =  decodeURIComponent(sanitized1string);
    
      var sanitized2string = fbKeySanitizer2(nameElt.value);
      sanitized2Elt.innerText = sanitized2string;
      decoded2Elt.innerText =  fbDecoded2(sanitized2string);
    }
    nameKeyUp();
    <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
    <form>
      <h1>Firebase invalid key characters escaping</h1>
      <label for="name">name:</label>
      <input id="name" onkeyup="nameKeyUp()" value="A%.B[#0]/x" />
      <hr>
      <form>
      <h3>Method One</h3>
      <p>Sanitized1: <span id="sanitized"></span></p>
      <p>Decoded1: <span id="decoded"></span></p>
      <hr>
      <h3>Method Two</h3>
      <p>Sanitized2: <span id="sanitized2"></span></p>
      <p>Decoded2: <span id="decoded2"></span></p>
    </form>

    【讨论】:

    • 有趣的想法:优点:在控制台中粘贴 URL 会容易得多缺点:任何字符编码错误都会给你留下 ascii 汤,我无法从键盘输入这些字符,那些chars 不再可用,您只剩下 unicode 的子集
    • 同意。我从 ascii 的一个子集开始,到 unicode 的一个子集结束。
    • 并非如此,出于往返 URI 编码的目的,可以将任何 unicode 输入并返回到完全相同的字符串。尝试使用您的函数对以下字符串进行编码然后解码:".$[\]#\/]․ᙚ⟦⟧⧣⧸" 并查看您得到的结果。 URI 编码/解码是无损的。
    • 我的意思是。使用 Firebase 你不能使用:'.$[]#/' 使用我的(有点功能失调的功能)你不能使用:'․ᙚ⟦⟧⧣⧸' 对于我们中的一些人来说可能就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2018-02-25
    相关资源
    最近更新 更多