วิธีการบันทึกข้อมูล | |
---|---|
ใส่ | เขียนหรือแทนที่ข้อมูลไปยัง เส้นทางที่กำหนด เช่น 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
เราสามารถอัปเดตลูกเฉพาะที่ตำแหน่งโดยไม่ต้องเขียนทับข้อมูลที่มีอยู่ มาเพิ่มชื่อเล่นของ 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'
หลังจากการอัปเดตนี้ ทั้งอลันและเกรซได้เพิ่มชื่อเล่น:
{ "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 กับธุรกรรม เพื่ออัปเดตข้อมูลตามสถานะที่มีอยู่ ตัวอย่างเช่น หากคุณต้องการเพิ่มตัวนับ upvote และต้องการให้แน่ใจว่าจำนวนนั้นสะท้อนถึง upvotes พร้อมกันหลายรายการอย่างถูกต้อง ให้ใช้คำขอแบบมีเงื่อนไขเพื่อเขียนค่าใหม่ไปยังตัวนับ แทนที่จะเขียนสองครั้งที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอเขียนรายการหนึ่งล้มเหลว จากนั้นคุณสามารถลองคำขออีกครั้งด้วยค่าใหม่- หากต้องการดำเนินการตามคำขอแบบมีเงื่อนไขที่ตำแหน่ง ให้รับตัวระบุเฉพาะสำหรับข้อมูลปัจจุบันที่ตำแหน่งนั้น หรือ 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 Realtime Database ที่ระบุไม่สามารถใช้งานได้ชั่วคราว ซึ่งหมายความว่าไม่ได้พยายามร้องขอ |
การรักษาความปลอดภัยข้อมูล
Firebase มีภาษารักษาความปลอดภัยที่ให้เรากำหนดว่าผู้ใช้คนใดมีสิทธิ์อ่านและเขียนในโหนดต่างๆ ของข้อมูลของเรา คุณสามารถอ่านเพิ่มเติมได้ใน กฎความปลอดภัยของฐานข้อมูลแบบเรียลไทม์
ตอนนี้เราได้กล่าวถึงการบันทึกข้อมูลแล้ว เราสามารถเรียนรู้วิธีดึงข้อมูลของเราจากฐานข้อมูล Firebase ผ่าน REST API ได้ในหัวข้อถัดไป