วิธีบันทึกข้อมูล |
|
---|---|
PUT | เขียนหรือแทนที่ข้อมูลตามเส้นทางที่กำหนด เช่น fireblog/users/user1/<data> |
แผ่นแปะ | อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ข้อมูลทั้งหมด |
โพสต์ | เพิ่มลงในรายการข้อมูลในฐานข้อมูล 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 รายการที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอการเขียนรายการหนึ่งจะล้มเหลว จากนั้นคุณจะลองส่งคำขออีกครั้งด้วยค่าใหม่ได้- หากต้องการส่งคำขอแบบมีเงื่อนไขที่ตำแหน่งหนึ่งๆ ให้รับตัวระบุที่ไม่ซ้ำกันสำหรับข้อมูลปัจจุบันในตำแหน่งนั้นหรือ ETag หากข้อมูลเปลี่ยนแปลงที่ตำแหน่งดังกล่าว ETag จะเปลี่ยนไปด้วย คุณขอ ETag ด้วยวิธีใดก็ได้ที่ไม่ใช่
PATCH
ตัวอย่างต่อไปนี้ใช้คำขอGET
curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
การเรียก ETag ในส่วนหัวแบบเฉพาะเจาะจงจะแสดง ETag ของตำแหน่งที่ระบุในการตอบกลับ HTTPHTTP/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
- ใส่ 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 อีกต่อไป ซึ่งอาจเกิดขึ้นหากผู้ใช้รายอื่นเขียนค่าใหม่ในฐานข้อมูล คำขอจะล้มเหลวโดยไม่ได้เขียนไปยังตำแหน่งดังกล่าว การตอบกลับคำขอจะมีค่าใหม่และ ETagHTTP/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
- โปรดใช้ข้อมูลใหม่หากคุณตัดสินใจส่งคำขออีกครั้ง 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
คำขอที่สำเร็จจะระบุด้วยรหัสสถานะ HTTP 200 OK
และการตอบกลับจะมีคีย์ของข้อมูลใหม่ที่เพิ่มเข้ามา ดังนี้
{"name":"-JSOpn9ZC54A4P4RoqVa"}
การลบข้อมูล
หากต้องการนำข้อมูลออกจากฐานข้อมูล เราสามารถส่งคำขอ DELETE
พร้อม URL ของเส้นทางที่เราต้องการลบข้อมูล ข้อมูลต่อไปนี้จะลบอลันออกจากเส้นทาง 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 และรองรับคำขอทุกประเภท อาร์กิวเมนต์อาจเป็นข้อมูลลับของแอป 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
, PUT
, POST
, PATCH
และ DELETE
รองรับ print=pretty
หากต้องการระงับเอาต์พุตจากเซิร์ฟเวอร์เมื่อเขียนข้อมูล เราจะเพิ่ม print=silent
ในคำขอได้ การตอบกลับที่ได้จะว่างเปล่าและระบุด้วยรหัสสถานะ HTTP 204 No Content
หากคำขอสำเร็จ
คำขอ GET
, PUT
, POST
และ PATCH
รองรับ print=silent
ค่าของเซิร์ฟเวอร์การเขียน
เขียนค่าเซิร์ฟเวอร์ในตําแหน่งหนึ่งๆ ได้โดยใช้ค่าตัวยึดตําแหน่ง ซึ่งเป็นออบเจ็กต์ที่มีคีย์ ".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 คำขอไม่ถูกต้อง |
เงื่อนไขข้อผิดพลาดข้อใดข้อหนึ่งต่อไปนี้
|
401 ไม่ได้รับอนุญาต |
เงื่อนไขข้อผิดพลาดข้อใดข้อหนึ่งต่อไปนี้
|
404 ไม่พบ | ไม่พบฐานข้อมูล Firebase ที่ระบุ |
500 ข้อผิดพลาดภายในเซิร์ฟเวอร์ | เซิร์ฟเวอร์แสดงผลข้อผิดพลาด โปรดดูรายละเอียดเพิ่มเติมในข้อความแสดงข้อผิดพลาด |
503 ไม่พร้อมให้บริการ | ฐานข้อมูลเรียลไทม์ของ Firebase ที่ระบุไม่พร้อมใช้งานชั่วคราว ซึ่งหมายความว่าไม่มีการพยายามส่งคำขอ |
การรักษาความปลอดภัยข้อมูล
Firebase มีภาษาเพื่อความปลอดภัยที่ช่วยให้เรากำหนดได้ว่าผู้ใช้คนใดมีสิทธิ์เข้าถึงโหนดข้อมูลแบบอ่านและเขียนได้ อ่านข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ในกฎความปลอดภัยของฐานข้อมูลแบบเรียลไทม์
เมื่อพูดถึงการบันทึกข้อมูลไปแล้ว เราก็ดูวิธีเรียกข้อมูลจากฐานข้อมูล Firebase ผ่าน REST API ได้ในส่วนถัดไป