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

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

PUT เขียนหรือแทนที่ข้อมูลไปยังเส้นทางที่กำหนด เช่น fireblog/users/user1/<data>
PATCH อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่แทนที่ข้อมูลทั้งหมด
POST เพิ่มลงในรายการข้อมูล ในฐานข้อมูล 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 และการตอบกลับจะมีข้อมูลที่เราเขียนลงในฐานข้อมูล ตัวอย่างแรกจะทริกเกอร์เหตุการณ์เดียวในไคลเอ็นต์ที่ดูข้อมูล ในขณะที่ตัวอย่างที่ 2 จะทริกเกอร์ 2 เหตุการณ์ โปรดทราบว่าหากมีข้อมูลอยู่ที่เส้นทางผู้ใช้อยู่แล้ว วิธีแรก จะเขียนทับข้อมูลนั้น แต่เมธอดที่ 2 จะแก้ไขเฉพาะค่าของโหนดลูกแต่ละรายการ โดยไม่เปลี่ยนแปลงลูกรายการอื่นๆ 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'

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

คำขอแบบมีเงื่อนไขที่อิงตาม REST จะใช้มาตรฐาน HTTP if-match อย่างไรก็ตาม คำขอเหล่านี้จะแตกต่างจากมาตรฐานในลักษณะต่อไปนี้

  • คุณระบุค่า ETag ได้เพียงค่าเดียวสำหรับคำขอ 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 ของเส้นทางที่เราต้องการลบข้อมูลได้ คำขอต่อไปนี้จะลบ 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 Realtime Database Security Rules และคำขอทุกประเภทรองรับพารามิเตอร์นี้ อาร์กิวเมนต์อาจเป็นข้อมูลลับของแอป 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 ลงในคำขอได้ การตอบกลับที่ได้จะเป็นการตอบกลับที่ว่างเปล่าและระบุด้วย รหัสสถานะ 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 คำขอไม่ถูกต้อง

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

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

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

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

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

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

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