Firebase การอัปเดตหลายตำแหน่ง

พิจารณาโค้ดต่อไปนี้สำหรับการเขียนแบบอะตอมมิกในหลายตำแหน่งใน FireBase:

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");

var newPostRef = ref.child("posts").push();
var newPostKey = newPostRef.key();

var updatedUserData = {};
updatedUserData["users/"+authData.uid+"/posts/" + newPostKey] = true;
updatedUserData["posts/" + newPostKey] = {
  title: "New Post",
  content: "Here is my new post!"
};

ref.update(updatedUserData, function(error) {
  if (error) {
    console.log("Error updating data:", error);
  }
});

วิธีการนี้สามารถใช้เพื่ออัปเดตโพสต์ในตำแหน่งต่างๆ แต่จะบังคับใช้การอัปเดตแบบอะตอมมิกที่ฝั่งเซิร์ฟเวอร์ได้อย่างไร (ตามกติกา)

ฉันจะแน่ใจได้อย่างไรว่าผู้ใช้ไม่สามารถอัปเดตตำแหน่ง /posts/ (ผ่านการอ้างอิงโดยตรง) โดยไม่ต้องเติม users/UID/posts/ หรือกลับกัน


person towi_parallelism    schedule 01.03.2016    source แหล่งที่มา


คำตอบ (1)


มี "กฎเกณฑ์ทางธุรกิจ" ที่เป็นไปได้หลายประการ ดังนั้นฉันจะเลือกกฎหนึ่งข้อและนำไปปฏิบัติ สมมติว่าโพสต์ใดๆ ที่ผู้ใช้อ้างถึงจะต้องมีอยู่ ดังนั้นคุณสามารถเขียนถึง /users/myuid/posts/mypostid ได้ก็ต่อเมื่อมี /posts/mypostid อยู่เท่านั้น ฉันจะใช้การตรวจสอบพื้นฐานของโพสต์ด้วย

{
  "posts": {
    "$postid": {
      ".validate": "hasChildren(['title', 'content'])",
      "title": {
        ".validate": "newData.isString()"
      },
      "content": {
        ".validate": "newData.isString()"
      },
      "$other": {
        ".validate": false
      }
    }
  },
  "users": {
    "$uid": {
      "posts": {
        "$postid": {
          ".validate": "newData.parent().parent().parent().parent().child('posts').child($postid).exists()
        }
      }
    }
  }
}

เคล็ดลับที่ใหญ่ที่สุดที่นี่คือบิต newData.parent().parent()... ซึ่งช่วยให้มั่นใจว่าเราได้รับโพสต์ในข้อมูลใหม่

คุณมีนิสัยชอบถามสิ่งต่างๆ เช่น "ฉันจะแน่ใจได้อย่างไรว่ามีการใช้วิธี ABC เพื่ออัปเดตข้อมูล" ซึ่งไม่ค่อยเป็นวิธีคิดที่ถูกต้องเกี่ยวกับเรื่องต่างๆ ในกฎข้างต้น ฉันมุ่งเน้นไปที่การตรวจสอบโครงสร้างของข้อมูล และไม่สนใจจริงๆ ว่าการเรียก API ใดที่อาจนำไปสู่ข้อมูลนั้น

person Frank van Puffelen    schedule 01.03.2016
comment
ขอบคุณ Frank ฉันใช้วิธีการที่คล้ายกัน แต่ฉันสับสนกับการใช้ newData.val() แทน exists().. อย่างไรก็ตาม ฉันเพิ่งเพิ่มแหล่งที่มาของส่วนการอัปเดตเพื่อให้ชัดเจนสำหรับผู้อ่านว่าฉัน m กำลังมองหาโซลูชันฝั่งเซิร์ฟเวอร์ที่รับประกันผลลัพธ์ที่ถูกต้อง ไม่ว่าจะเกิดอะไรขึ้นที่ฝั่งไคลเอ็นต์... แต่อย่างไรก็ตาม ขอบคุณสำหรับคำตอบ แก้ไขปัญหาของฉัน :) - person towi_parallelism; 01.03.2016
comment
หากคุณมีแนวทางที่ไม่ได้ผลอยู่แล้ว ให้เสมอโพสต์สิ่งที่คุณมีในคำถามของคุณ แสดงว่าคุณได้ลองบางอย่างแล้ว และยังช่วยให้เราสามารถคัดลอก/วางตัวอย่างข้อมูลลงในคำตอบของเราได้ - person Frank van Puffelen; 01.03.2016
comment
อ้างถึงคำถามนี้ newData.parent()... สามารถใช้หลายครั้งภายในกฎ ".validate" ของโหนดเฉพาะได้หรือไม่ - person Andrey; 21.10.2016