กำลังบันทึกข้อมูล

วิธีบันทึกข้อมูล

PUT เขียนหรือแทนที่ข้อมูลตามเส้นทางที่กำหนด เช่น fireblog/users/user1/<data>
แผ่นแปะ อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ข้อมูลทั้งหมด
POST เพิ่มลงในรายการข้อมูลในฐานข้อมูล Firebase ทุกครั้งที่เราส่งคำขอ POST ไคลเอ็นต์ Firebase จะสร้างคีย์ที่ไม่ซ้ำกัน เช่น fireblog/users/<unique-id>/<data>
ลบ นำข้อมูลออกจากการอ้างอิงฐานข้อมูล Firebase ที่ระบุ

การเขียนข้อมูลด้วย PUT

การดำเนินการเขียนพื้นฐานผ่าน REST API คือ PUT ถึง แสดงให้เห็นถึงการประหยัดข้อมูล เราจะสร้างแอปพลิเคชันการเขียนบล็อกที่มีโพสต์และผู้ใช้ ทั้งหมด ข้อมูลสำหรับแอปพลิเคชันของเราจะจัดเก็บอยู่ภายใต้เส้นทางของ "fireblog" ที่ URL ของฐานข้อมูล Firebase "https://docs-examples.firebaseio.com/fireblog"

เริ่มต้นด้วยการบันทึกข้อมูลผู้ใช้บางส่วนลงในฐานข้อมูล Firebase เราจะจัดเก็บผู้ใช้แต่ละรายตาม ชื่อผู้ใช้ และเราจะจัดเก็บชื่อเต็มและวันเกิดของผู้ใช้ไว้ด้วย เนื่องจากผู้ใช้แต่ละรายจะมี ชื่อผู้ใช้ไม่ซ้ำ จึงเป็นการเหมาะสมที่จะใช้ PUT ที่นี่แทน POST เนื่องจาก เรามีคีย์อยู่แล้วและไม่จำเป็นต้องสร้างคีย์

เมื่อใช้ PUT เราจะเขียนสตริง ตัวเลข บูลีน อาร์เรย์ หรือออบเจ็กต์ JSON ใดก็ได้ลงใน ฐานข้อมูล Firebase ของเรา ในกรณีนี้ เราจะส่งออบเจ็กต์ต่อไปนี้ไปให้

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

เมื่อบันทึกออบเจ็กต์ JSON ลงในฐานข้อมูล คุณสมบัติของออบเจ็กต์ แมปกับตำแหน่งย่อยในแบบซ้อนกันโดยอัตโนมัติ ถ้าเรานำทางไปที่ กับโหนดที่สร้างใหม่ เราจะเห็นค่า "Alan Turing" เรายังสามารถ บันทึกข้อมูลไปยัง ตำแหน่งของบุตรหลาน:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

ตัวอย่าง 2 ข้อข้างต้น ซึ่งก็คือการเขียนค่าพร้อมกันเป็นออบเจ็กต์แล้วเขียนค่า ไปยังตำแหน่งย่อย จะทำให้ระบบบันทึกข้อมูลเดียวกันไว้ใน Firebase ฐานข้อมูล:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

คำขอที่ประสบความสำเร็จจะระบุด้วยรหัสสถานะ HTTP 200 OK และ จะมีข้อมูลที่เราเขียนลงในฐานข้อมูล ตัวอย่างแรกจะ เรียก 1 เหตุการณ์ในไคลเอ็นต์ที่ดูข้อมูล ส่วนตัวอย่างที่ 2 จะทริกเกอร์ 2. คุณควรทราบว่าหากมีข้อมูลอยู่แล้วในเส้นทางของผู้ใช้ แนวทางแรก จะเขียนทับ แต่วิธีที่ 2 จะแก้ไขเฉพาะค่าของรายการย่อยแต่ละรายการ ขณะที่ปล่อยรายการย่อยอื่นๆ ไว้โดยไม่มีการเปลี่ยนแปลง PUT เทียบเท่ากับ set() ใน JavaScript SDK ของเรา

การอัปเดตข้อมูลด้วยแพตช์

การใช้คำขอPATCHช่วยให้เราอัปเดตบุตรหลานที่เจาะจงในสถานที่หนึ่งๆ ได้โดยไม่ต้อง เขียนทับข้อมูลที่มีอยู่ เพิ่มชื่อเล่นของ Turing ลงในข้อมูลผู้ใช้ด้วย PATCH คำขอ:

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

คำขอข้างต้นจะเขียน nickname ในออบเจ็กต์ alanisawesome ของเรา โดยไม่ลบองค์ประกอบย่อย name หรือ birthday โปรดทราบว่าถ้าเรามี ได้ออกคำขอPUTที่นี่แทน name และbirthday จะถูกลบเนื่องจากไม่ได้รวมอยู่ในคำขอ ข้อมูลใน Firebase ของเรา ตอนนี้ฐานข้อมูลจะมีหน้าตาแบบนี้

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

คำขอที่ประสบความสำเร็จจะระบุด้วยรหัสสถานะ HTTP 200 OK และ จะมีข้อมูลที่อัปเดตซึ่งเขียนลงในฐานข้อมูล

นอกจากนี้ Firebase ยังรองรับการอัปเดตหลายเส้นทางด้วย ซึ่งหมายความว่าตอนนี้ PATCH สามารถอัปเดตค่าในฐานข้อมูล Firebase ของคุณได้หลายแห่งพร้อมกัน ซึ่งเป็นฟีเจอร์ที่มีประสิทธิภาพที่ช่วยให้คุณ ทำให้ข้อมูลผิดมาตรฐาน เมื่อใช้การอัปเดตหลายเส้นทาง เราสามารถเพิ่มชื่อเล่นให้ทั้ง Alan และ Grace พร้อมกันได้

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

หลังจากการอัปเดตครั้งนี้ ทั้ง Alan และ Grace ได้เพิ่มชื่อเล่นของพวกเขาเข้ามา:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

โปรดทราบว่าการพยายามอัปเดตออบเจ็กต์ด้วยการเขียนออบเจ็กต์ด้วยเส้นทางที่รวมอยู่จะส่งผลให้เกิดลักษณะการทำงานที่ต่างกัน เรามาดูกันว่าจะเกิดอะไรขึ้นถ้าเราลองอัปเดต Grace และ Alan ด้วยวิธีนี้

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

การดำเนินการนี้จะส่งผลให้เกิดพฤติกรรมที่ต่างกัน กล่าวคือ การเขียนทับโหนด /fireblog/users ทั้งโหนด:

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

การอัปเดตข้อมูลด้วยคำขอแบบมีเงื่อนไข

คุณสามารถใช้คำขอแบบมีเงื่อนไขซึ่งเทียบเท่ากับ REST ที่เทียบเท่ากับธุรกรรม เพื่ออัปเดต ตามสถานะที่มีอยู่ สำหรับ เช่น หากคุณต้องการเพิ่มจำนวนการโหวตเห็นด้วย และต้องการให้ นับอย่างถูกต้อง ซึ่งแสดงให้เห็นถึงการโหวตเห็นด้วยพร้อมกันหลายรายการ ใช้เงื่อนไข เพื่อเขียนค่าใหม่ลงในตัวนับ แทนการเขียน 2 รายการ ที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอการเขียนรายการหนึ่งล้มเหลวและ จากนั้น คุณจะลองส่งคำขออีกครั้งด้วยค่าใหม่ได้
  1. รับตัวระบุที่ไม่ซ้ำกันเพื่อส่งคำขอแบบมีเงื่อนไขที่สถานที่ตั้ง สำหรับข้อมูลปัจจุบัน ณ ตำแหน่งนั้นหรือ ETag หากข้อมูลเปลี่ยนแปลง ณ ตำแหน่งนั้น ETag จะเปลี่ยนไปด้วย คุณสามารถขอ ETag ด้วย วิธีอื่นที่ไม่ใช่ PATCH ตัวอย่างต่อไปนี้ใช้คำขอ GET
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    
    การเรียก ETag ในส่วนหัวโดยเฉพาะจะแสดง ETag ของ ตำแหน่งที่ระบุในการตอบสนอง HTTP
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
    
  2. รวม ETag ที่ส่งคืนไว้ใน PUT หรือ DELETE ถัดไปของคุณ ขออัปเดต ข้อมูลที่ตรงกับค่า ETag ดังกล่าวโดยเฉพาะ จากตัวอย่างของเราในการ อัปเดตตัวนับเป็น 11 หรือ 1 ที่ใหญ่กว่าค่าที่ดึงมาเริ่มต้นที่ 10 และจะไม่ดำเนินการตามคำขอหากค่าไม่ตรงกันอีกต่อไป ให้ใช้โค้ดต่อไปนี้
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    
    หากค่าของข้อมูลในตำแหน่งที่ระบุยังคงเป็น 10 ETag ใน คำขอตรงกัน PUT รายการ และคำขอสำเร็จ โดยการเขียน 11 รายการไปยังฐานข้อมูล
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    
    หากสถานที่ตั้งไม่ตรงกับ ETag แล้ว ซึ่งอาจเกิดขึ้นหากผู้ใช้รายอื่น เขียนค่าใหม่ลงในฐานข้อมูลแล้ว คำขอล้มเหลวโดยไม่ได้เขียนไปยัง ตำแหน่งนั้น การตอบกลับคำขอจะมีค่าใหม่และ ETag
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
    
  3. โปรดใช้ข้อมูลใหม่หากคุณตัดสินใจส่งคำขออีกครั้ง Realtime Database จะไม่ลองทำคำขอแบบมีเงื่อนไขที่ล้มเหลวซ้ำโดยอัตโนมัติ อย่างไรก็ตาม คุณสามารถใช้ค่าใหม่และ ETag เพื่อสร้างคำขอแบบมีเงื่อนไขใหม่ด้วย ข้อมูลที่แสดงผลผ่านการตอบกลับที่ไม่สำเร็จ

คำขอแบบมีเงื่อนไขที่อิงตาม REST จะใช้ HTTP if-match มาตรฐาน อย่างไรก็ตาม ค่าเหล่านี้จะแตกต่างจากมาตรฐานดังนี้

  • คุณระบุค่า ETag ได้เพียง 1 ค่าต่อคำขอ if-Match แต่ละรายการ ไม่ใช่หลายค่า
  • แม้ว่ามาตรฐานจะชี้ให้เห็นว่า ETag มีการส่งคืนพร้อมคำขอทั้งหมด Realtime Database จะแสดงเฉพาะ ETag ที่มีคำขอรวม ส่วนหัว X-Firebase-ETag ซึ่งจะลดต้นทุนการเรียกเก็บเงินสำหรับคำขอมาตรฐาน

คำขอแบบมีเงื่อนไขยังอาจช้ากว่าคำขอ REST ทั่วไปด้วย

การบันทึกรายการข้อมูล

เพื่อสร้างคีย์ตามการประทับเวลาที่ไม่ซ้ำกันสำหรับผู้เผยแพร่โฆษณาย่อยทุกคนที่เพิ่มลงในการอ้างอิงฐานข้อมูล Firebase เราส่งคำขอPOSTได้ สำหรับเส้นทาง users ของเรา คุณควร กำหนดคีย์ของเราเอง เนื่องจากผู้ใช้แต่ละคนจะมีชื่อผู้ใช้ที่ไม่ซ้ำกัน แต่เมื่อผู้ใช้เพิ่มบล็อกโพสต์ลงใน เราจะใช้คำขอ POST เพื่อสร้างคีย์สำหรับบล็อกโพสต์แต่ละรายการโดยอัตโนมัติ

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

เส้นทาง posts ของเรามีข้อมูลต่อไปนี้แล้วในตอนนี้

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

โปรดทราบว่ามีการสร้างคีย์ -JSOpn9ZC54A4P4RoqVa ให้กับเราโดยอัตโนมัติเนื่องจาก เราใช้คำขอ POST คำขอที่สำเร็จจะได้รับการระบุด้วย 200 OK รหัสสถานะ HTTP และการตอบกลับจะมีคีย์ของข้อมูลใหม่ที่เพิ่มเข้ามา ดังนี้

{"name":"-JSOpn9ZC54A4P4RoqVa"}

การลบข้อมูล

หากต้องการนำข้อมูลออกจากฐานข้อมูล เราสามารถส่งคำขอ DELETE พร้อม URL ของเส้นทางที่เราต้องการลบข้อมูล รายการต่อไปนี้จะลบ Alan ออกจาก เส้นทาง users:

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

คำขอ DELETE ที่สำเร็จจะระบุด้วยรหัสสถานะ HTTP 200 OK พร้อมการตอบกลับที่มี JSON null

พารามิเตอร์ URI

REST API จะยอมรับพารามิเตอร์ URI ต่อไปนี้เมื่อเขียนข้อมูลไปยังฐานข้อมูล

การตรวจสอบสิทธิ์

พารามิเตอร์คำขอ auth อนุญาตให้เข้าถึงข้อมูลที่ได้รับการปกป้องโดย Firebase Realtime Database Security Rules และเป็น รองรับคำขอทุกประเภท อาร์กิวเมนต์อาจเป็นข้อมูลลับของแอป Firebase หรือ โทเค็นการตรวจสอบสิทธิ์ ซึ่งเราจะอธิบายในการให้สิทธิ์ผู้ใช้ ในตัวอย่างต่อไปนี้ เราส่งคำขอ POST ที่มี auth โดยที่ CREDENTIAL เป็นข้อมูลลับของแอป Firebase หรือ โทเค็นการตรวจสอบสิทธิ์

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

พิมพ์

พารามิเตอร์ print ช่วยให้เราระบุรูปแบบการตอบสนองจาก ฐานข้อมูล การเพิ่ม print=pretty ในคำขอจะแสดงข้อมูลใน ที่มนุษย์อ่านได้ GET รองรับ print=pretty คำขอ PUT, POST, PATCH และ DELETE

ในการระงับการแสดงผลจากเซิร์ฟเวอร์ขณะเขียนข้อมูล เราสามารถเพิ่ม print=silent ตามคำขอของเรา การตอบกลับที่ได้จะว่างเปล่าและระบุด้วย รหัสสถานะ HTTP 204 No Content หากคำขอดำเนินการสำเร็จ แท็ก print=silent รองรับโดย GET PUT POST และ PATCH คำขอ

ค่าของเซิร์ฟเวอร์การเขียน

ค่าเซิร์ฟเวอร์สามารถเขียนไว้ในตำแหน่งหนึ่งๆ โดยใช้ค่าตัวยึดตำแหน่งซึ่งเป็นออบเจ็กต์ที่มี คีย์ ".sv" เดี่ยว ค่าสำหรับคีย์นั้นเป็นประเภทของค่าของเซิร์ฟเวอร์ที่เรากำหนด เช่น ในการตั้งค่าการประทับเวลาเมื่อสร้างผู้ใช้ เราสามารถทำดังนี้

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" เป็นค่าของเซิร์ฟเวอร์ที่รองรับเพียงค่าเดียว และเป็นค่าที่ระบุเป็นเวลานับตั้งแต่ UNIX Epoch ในหน่วยมิลลิวินาที

การปรับปรุงประสิทธิภาพการเขียน

หากเรากำลังเขียนข้อมูลจำนวนมากลงในฐานข้อมูล เราสามารถใช้ print=silent เพื่อปรับปรุงประสิทธิภาพการเขียนและลดแบนด์วิดท์ ในการทำงานเขียนปกติ เซิร์ฟเวอร์จะตอบสนองด้วยข้อมูล JSON ที่เขียนขึ้น เมื่อระบุ print=silent แล้ว เซิร์ฟเวอร์จะ ปิดการเชื่อมต่อเมื่อได้รับข้อมูล ลดการใช้แบนด์วิดท์

ในกรณีที่เราส่งคำขอไปยังฐานข้อมูลจำนวนมาก เราสามารถนำ HTTPS กลับมาใช้ซ้ำ การเชื่อมต่อโดยส่งคำขอ Keep-Alive ในส่วนหัว HTTP

เงื่อนไขข้อผิดพลาด

REST API จะแสดงรหัสข้อผิดพลาดในสถานการณ์ต่อไปนี้

รหัสสถานะ HTTP
400 คำขอไม่ถูกต้อง

เงื่อนไขข้อผิดพลาดข้อใดข้อหนึ่งต่อไปนี้

  • แยกวิเคราะห์ข้อมูล PUT หรือ POST ไม่ได้
  • ไม่มีข้อมูล PUT หรือ POST
  • คำขอพยายามจะPUTหรือPOSTข้อมูล มีขนาดใหญ่เกินไป
  • การเรียก API ของ REST มีชื่อย่อยที่ไม่ถูกต้องเป็นส่วนหนึ่งของเส้นทาง
  • เส้นทางการเรียก API ของ REST ยาวเกินไป
  • คำขอมีค่าเซิร์ฟเวอร์ที่ไม่รู้จัก
  • ดัชนีสำหรับการค้นหาไม่ได้กำหนดไว้ใน Firebase Realtime Database Security Rules
  • คำขอไม่สนับสนุนพารามิเตอร์การค้นหาที่ระบุ
  • คำขอจะผสมพารามิเตอร์การค้นหาเข้ากับคำขอ GET แบบตื้น
401 ไม่ได้รับอนุญาต

เงื่อนไขข้อผิดพลาดข้อใดข้อหนึ่งต่อไปนี้

  • โทเค็นการตรวจสอบสิทธิ์หมดอายุแล้ว
  • โทเค็นการตรวจสอบสิทธิ์ที่ใช้ในคำขอไม่ถูกต้อง
  • การตรวจสอบสิทธิ์ด้วย Access_token ล้มเหลว
  • คำขอนี้ละเมิด Firebase Realtime Database Security Rules
404 ไม่พบ ไม่พบฐานข้อมูล Firebase ที่ระบุ
500 ข้อผิดพลาดภายในเซิร์ฟเวอร์ เซิร์ฟเวอร์แสดงผลข้อผิดพลาด โปรดดูรายละเอียดเพิ่มเติมในข้อความแสดงข้อผิดพลาด
503 ไม่พร้อมให้บริการ ฐานข้อมูลเรียลไทม์ของ Firebase ที่ระบุไม่พร้อมใช้งานชั่วคราว ซึ่งหมายความว่า ไม่มีการพยายามส่งคำขอ

การรักษาความปลอดภัยข้อมูล

Firebase มีภาษาเพื่อความปลอดภัยที่ช่วยให้เรากำหนดได้ว่าผู้ใช้รายใดมีสิทธิ์เข้าถึงการอ่านและเขียน โหนดต่างๆ ของข้อมูล อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ใน Realtime Database Security Rules

เมื่อเราพูดถึงการบันทึกข้อมูลกันไปแล้ว เราจะมาเรียนรู้วิธีดึงข้อมูลจาก Firebase ผ่าน REST API ในส่วนถัดไป