วิธีบันทึกข้อมูล | |
---|---|
ใส่ | เขียนหรือแทนที่ข้อมูลไปยัง เส้นทางที่กำหนด เช่น 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'
สองตัวอย่างข้างต้น—การเขียนค่าพร้อมกับออบเจ็กต์และเขียนแยกกันไปยังตำแหน่งลูก—จะส่งผลให้ข้อมูลเดียวกันถูกบันทึกลงในฐานข้อมูล Firebase ของเรา:
{ "users": { "alanisawesome": { "date_of_birth": "June 23, 1912", "full_name": "Alan Turing" } } }
คำขอที่สำเร็จจะถูกระบุด้วยรหัสสถานะ HTTP 200 OK
และการตอบกลับจะมีข้อมูลที่เราเขียนลงในฐานข้อมูล ตัวอย่างแรกจะทริกเกอร์เพียงเหตุการณ์เดียวบนไคลเอนต์ที่กำลังดูข้อมูล ในขณะที่ตัวอย่างที่สองจะทริกเกอร์สองเหตุการณ์ สิ่งสำคัญคือต้องสังเกตว่า หากมีข้อมูลอยู่แล้วในเส้นทางผู้ใช้ วิธีแรกจะเขียนทับข้อมูลนั้น แต่วิธีที่สองจะแก้ไขค่าของโหนดลูกแต่ละโหนดที่แยกจากกันเท่านั้น โดยปล่อยให้ลูกอื่นๆ ไม่เปลี่ยนแปลง 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
จะถูกลบเนื่องจากไม่ได้รวมอยู่ในคำขอ ข้อมูลในฐานข้อมูล 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 ซึ่งเทียบเท่ากับธุรกรรม เพื่ออัปเดตข้อมูลตามสถานะที่มีอยู่ ตัวอย่างเช่น หากคุณต้องการเพิ่มตัวนับการโหวตเห็นด้วย และต้องการให้แน่ใจว่าการนับนั้นสะท้อนถึงการโหวตเห็นด้วยหลายรายการพร้อมกันอย่างถูกต้อง ให้ใช้คำขอแบบมีเงื่อนไขเพื่อเขียนค่าใหม่ไปที่ตัวนับ แทนที่จะเขียนสองครั้งที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอเขียนรายการใดรายการหนึ่งล้มเหลว และคุณสามารถลองคำขออีกครั้งด้วยค่าใหม่ได้- หากต้องการดำเนินการร้องขอแบบมีเงื่อนไข ณ ตำแหน่งนั้น ให้รับตัวระบุที่ไม่ซ้ำกันสำหรับข้อมูลปัจจุบัน ณ ตำแหน่งนั้นหรือ 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
- ใช้ข้อมูลใหม่หากคุณตัดสินใจลองส่งคำขออีกครั้ง ฐานข้อมูลเรียลไทม์ไม่ลองคำขอแบบมีเงื่อนไขที่ล้มเหลวอีกครั้งโดยอัตโนมัติ อย่างไรก็ตาม คุณสามารถใช้ค่าใหม่และ ETag เพื่อสร้างคำขอแบบมีเงื่อนไขใหม่พร้อมข้อมูลที่ส่งคืนโดยการตอบกลับที่ล้มเหลว
คำขอแบบมีเงื่อนไขที่ใช้ REST จะใช้มาตรฐาน HTTP if-match อย่างไรก็ตาม จะแตกต่างจากมาตรฐานในลักษณะดังต่อไปนี้:
- คุณสามารถระบุค่า ETag ได้เพียงค่าเดียวสำหรับคำขอ if-match แต่ละรายการ ไม่สามารถระบุหลายค่าได้
- แม้ว่ามาตรฐานจะแนะนำให้ส่งคืน ETags พร้อมคำขอทั้งหมด แต่ Realtime Database จะส่งคืน ETags พร้อมคำขอรวมถึงส่วนหัว
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 และได้รับการสนับสนุนจากคำขอทุกประเภท อาร์กิวเมนต์อาจเป็นข้อมูลลับของแอป 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
ลงในคำขอของเราได้ ผลลัพธ์ที่ได้จะว่างเปล่าและระบุด้วยรหัสสถานะ 204 No Content
HTTP หากคำขอสำเร็จ print=silent
ได้รับการสนับสนุนโดยคำขอ GET
, PUT
, POST
และ PATCH
การเขียนค่าเซิร์ฟเวอร์
ค่าเซิร์ฟเวอร์สามารถเขียน ณ ตำแหน่งหนึ่งได้โดยใช้ค่าตัวยึดตำแหน่ง ซึ่งเป็นออบเจ็กต์ที่มีคีย์ ".sv"
เพียงคีย์เดียว ค่าสำหรับคีย์นั้นคือประเภทของค่าเซิร์ฟเวอร์ที่เราต้องการตั้งค่า ตัวอย่างเช่น หากต้องการตั้งค่าการประทับเวลาเมื่อมีการสร้างผู้ใช้ เราสามารถทำได้ดังต่อไปนี้:
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
เป็นค่าเซิร์ฟเวอร์เดียวที่รองรับ และเป็นเวลานับตั้งแต่ยุค UNIX ในหน่วยมิลลิวินาที
การปรับปรุงประสิทธิภาพการเขียน
หากเรากำลังเขียนข้อมูลจำนวนมากลงในฐานข้อมูล เราสามารถใช้พารามิเตอร์ print=silent
เพื่อปรับปรุงประสิทธิภาพการเขียนของเราและลดการใช้แบนด์วิดท์ ในลักษณะการเขียนปกติ เซิร์ฟเวอร์จะตอบกลับด้วยข้อมูล JSON ที่ถูกเขียน เมื่อระบุ print=silent
เซิร์ฟเวอร์จะปิดการเชื่อมต่อทันทีเมื่อได้รับข้อมูล ช่วยลดการใช้แบนด์วิธ
ในกรณีที่เราส่งคำขอจำนวนมากไปยังฐานข้อมูล เราสามารถใช้การเชื่อมต่อ HTTPS อีกครั้งได้โดยส่งคำขอ Keep-Alive
ในส่วนหัว HTTP
เงื่อนไขข้อผิดพลาด
REST API จะส่งกลับรหัสข้อผิดพลาดภายใต้สถานการณ์เหล่านี้:
รหัสสถานะ HTTP | |
---|---|
400 คำขอไม่ถูกต้อง | เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้:
|
401 ไม่ได้รับอนุญาต | เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้:
|
404 ไม่พบ | ไม่พบฐานข้อมูล Firebase ที่ระบุ |
500 ข้อผิดพลาดภายในเซิร์ฟเวอร์ | เซิร์ฟเวอร์ส่งคืนข้อผิดพลาด ดูข้อความแสดงข้อผิดพลาดสำหรับรายละเอียดเพิ่มเติม |
503 บริการไม่พร้อมใช้งาน | ฐานข้อมูลเรียลไทม์ Firebase ที่ระบุไม่พร้อมใช้งานชั่วคราว ซึ่งหมายความว่าไม่ได้พยายามร้องขอ |
การรักษาความปลอดภัยข้อมูล
Firebase มีภาษาความปลอดภัยที่ช่วยให้เรากำหนดได้ว่าผู้ใช้รายใดมีสิทธิ์อ่านและเขียนการเข้าถึงโหนดต่างๆ ของข้อมูลของเรา คุณสามารถอ่านเพิ่มเติมได้ใน กฎความปลอดภัยของฐานข้อมูลแบบเรียลไทม์
ตอนนี้เราได้กล่าวถึงการบันทึกข้อมูลแล้ว เราสามารถเรียนรู้วิธีดึงข้อมูลของเราจากฐานข้อมูล Firebase ผ่าน REST API ได้ในส่วนถัดไป