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

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

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

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

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

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

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

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

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

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