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

วิธีประหยัดอินเทอร์เน็ต

PUT เขียนหรือแทนที่ข้อมูลไปยังเส้นทางที่กำหนด เช่น fireblog/users/user1/<data>
PATCH อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ข้อมูลทั้งหมด
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"
    }
  }
}

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

การอัปเดตข้อมูลด้วย PATCH

การใช้PATCHคำขอจะช่วยให้เราอัปเดตเด็กที่เฉพาะเจาะจงในสถานที่หนึ่งๆ ได้โดยไม่ต้อง เขียนทับข้อมูลที่มีอยู่ มาเพิ่มชื่อเล่นของทัวริงลงในข้อมูลผู้ใช้ด้วย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 ระบบจะลบnameและbirthdayเนื่องจากไม่ได้รวมอยู่ในคำขอ ตอนนี้ข้อมูลในฐานข้อมูล Firebase มีลักษณะดังนี้

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

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

นอกจากนี้ 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'

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

{
  "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 ได้เพียงค่าเดียวสำหรับคำขอ 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 คำขอที่สำเร็จจะระบุด้วยรหัสสถานะ HTTP 200 OK และการตอบกลับจะมีคีย์ของข้อมูลใหม่ที่เพิ่มเข้ามา

{"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 ในคำขอจะแสดงข้อมูลในรูปแบบที่มนุษย์อ่านได้ print=pretty รองรับคำขอ GET, 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" เป็นค่าเซิร์ฟเวอร์เดียวที่รองรับ และเป็นเวลาตั้งแต่ Epoch ของ UNIX ในหน่วยมิลลิวินาที

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

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

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

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

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

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

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

  • แยกวิเคราะห์ข้อมูล PUT หรือ POST ไม่ได้
  • ไม่มีข้อมูล PUT หรือ POST
  • คำขอพยายามPUTหรือPOSTข้อมูลที่มีขนาดใหญ่เกินไป
  • การเรียก REST API มีชื่อย่อยที่ไม่ถูกต้องเป็นส่วนหนึ่งของเส้นทาง
  • เส้นทางการเรียก REST API ยาวเกินไป
  • คำขอมีค่าเซิร์ฟเวอร์ที่ไม่รู้จัก
  • ไม่ได้กำหนดดัชนีสำหรับคำค้นหาใน 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 กัน