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

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

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

ใส่ เขียนหรือแทนที่ข้อมูลเป็น เส้นทางที่กำหนด เช่น 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"
    }
  }
}

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

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 ที่เทียบเท่ากับธุรกรรม เพื่ออัปเดตข้อมูลตามสถานะที่มีอยู่ ตัวอย่างเช่น หากคุณต้องการเพิ่มตัวนับการโหวตเห็นด้วย และต้องการให้แน่ใจว่าการนับนั้นสะท้อนการโหวตเห็นด้วยหลายครั้งได้อย่างแม่นยำ ให้ใช้คำขอแบบมีเงื่อนไขเพื่อเขียนค่าใหม่ไปยังตัวนับ แทนที่จะเขียนสองครั้งที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอเขียนรายการใดรายการหนึ่งล้มเหลว และคุณสามารถลองคำขออีกครั้งด้วยค่าใหม่
  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. ใช้ข้อมูลใหม่หากคุณตัดสินใจที่จะลองส่งคำขออีกครั้ง ฐานข้อมูลเรียลไทม์ไม่ลองส่งคำขอแบบมีเงื่อนไขที่ล้มเหลวอีกครั้งโดยอัตโนมัติ อย่างไรก็ตาม คุณสามารถใช้ค่าใหม่และ 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 พร้อมพารามิเตอร์การตรวจสอบสิทธิ์ CREDENTIAL auth ความลับของแอป 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 คำขอไม่ถูกต้อง

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

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

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

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

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

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

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