Đọc dữ liệu bằng GET
Chúng ta có thể đọc dữ liệu từ cơ sở dữ liệu Firebase bằng cách gửi yêu cầu GET đến điểm cuối URL
của cơ sở dữ liệu đó. Hãy tiếp tục với ví dụ về blog trong phần trước và đọc tất cả dữ liệu bài đăng trên blog của chúng ta:
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'
Yêu cầu thành công sẽ được biểu thị bằng mã trạng thái HTTP 200 OK và phản hồi sẽ chứa dữ liệu mà chúng ta đang truy xuất.
Thêm tham số URI
API REST chấp nhận một số tham số truy vấn khi đọc dữ liệu từ cơ sở dữ liệu Firebase. Dưới đây là danh sách các tham số thường dùng nhất. Để xem danh sách đầy đủ, hãy tham khảo Tài liệu tham khảo về API REST.
auth
Tham số yêu cầu auth cho phép truy cập vào dữ liệu được bảo vệ bằng
Firebase Realtime Database Security Rules, và được
tất cả các loại yêu cầu hỗ trợ. Đối số có thể là bí mật của ứng dụng Firebase hoặc mã xác thực, như mô tả trong phần Người dùng trong dự án Firebase. Trong ví dụ sau, chúng ta gửi yêu cầu GET có tham số auth
, trong đó CREDENTIAL là bí mật của ứng dụng Firebase hoặc
mã xác thực:
curl 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
in
Việc chỉ định print=pretty sẽ trả về dữ liệu ở định dạng mà con người có thể đọc được.
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'
Việc chỉ định print=silent sẽ trả về 204 No Content khi thành công.
curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=silent'
callback
Để thực hiện lệnh gọi REST từ trình duyệt web trên các miền, bạn có thể sử dụng
JSONP để gói phản hồi trong hàm gọi lại JavaScript. Thêm callback= để API REST gói dữ liệu được trả về trong
hàm gọi lại mà bạn chỉ định. Ví dụ:
<script>
function gotData(data) {
console.log(data);
}
</script>
<script src="https://docs-examples.firebaseio.com/fireblog/posts.json?callback=gotData">shallow
Đây là một tính năng nâng cao, được thiết kế để giúp bạn làm việc với các tập dữ liệu lớn mà không cần tải xuống mọi thứ. Để sử dụng tính năng này, hãy thêm shallow=true làm tham số. Điều này sẽ giới hạn
độ sâu của dữ liệu được trả về. Nếu dữ liệu tại vị trí đó là một nguyên thuỷ JSON (chuỗi, số,
hoặc boolean), thì giá trị của dữ liệu đó sẽ được trả về. Nếu ảnh chụp nhanh dữ liệu tại vị trí đó là một đối tượng JSON, thì giá trị của mỗi khoá sẽ bị cắt ngắn thành true. Ví dụ: sử dụng
dữ liệu bên dưới:
{ "message": { "user": { "name": "Chris" }, "body": "Hello!" } } // A request to /message.json?shallow=true // would return the following: { "user": true, "body": true } // A request to /message/body.json?shallow=true // would simply return: "Hello!"
Hãy thử với yêu cầu curl này:
curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?shallow=true&print=pretty'
timeout
Hãy sử dụng tham số này để giới hạn thời gian đọc ở phía máy chủ. Nếu yêu cầu đọc không hoàn tất trong thời gian được phân bổ, thì yêu cầu đó sẽ kết thúc bằng lỗi HTTP 400. Điều này đặc biệt hữu ích khi bạn dự kiến chuyển một lượng nhỏ dữ liệu và không muốn chờ quá lâu để tìm nạp một cây con có khả năng rất lớn. Thời gian đọc thực tế có thể khác nhau dựa trên kích thước dữ liệu và bộ nhớ đệm.
Chỉ định timeouts bằng cách sử dụng định dạng sau: 3ms,
3s hoặc 3min, với một số và một đơn vị. Nếu bạn không
chỉ định, thì timeout tối đa là 15min sẽ được
áp dụng. Nếu timeout không dương hoặc vượt quá mức tối đa,
thì yêu cầu sẽ bị từ chối với lỗi HTTP 400.
Trong ví dụ sau, yêu cầu GET bao gồm
timeout là 10 giây.
curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?timeout=10s'
Lọc dữ liệu
Chúng ta có thể tạo truy vấn để lọc dữ liệu dựa trên nhiều yếu tố. Để bắt đầu, bạn chỉ định cách bạn muốn lọc dữ liệu bằng tham số orderBy. Sau đó, bạn kết hợp orderBy với bất kỳ tham số nào trong số 5 tham số còn lại:
limitToFirst, limitToLast, startAt, endAt,
và equalTo.
Vì tất cả chúng ta tại Firebase đều nghĩ rằng khủng long khá thú vị, nên chúng ta sẽ sử dụng một đoạn mã từ cơ sở dữ liệu mẫu về các sự kiện khủng long để minh hoạ cách bạn có thể lọc dữ liệu:
{
"lambeosaurus": {
"height": 2.1,
"length": 12.5,
"weight": 5000
},
"stegosaurus": {
"height": 4,
"length": 9,
"weight": 2500
}
}
Chúng ta có thể lọc dữ liệu theo một trong 3 cách: theo khoá con, theo khoá hoặc theo
giá trị. Truy vấn bắt đầu bằng một trong các tham số này, sau đó phải được kết hợp với một hoặc nhiều tham số sau: startAt, endAt, limitToFirst, limitToLast hoặc equalTo.
Lọc theo khoá con đã chỉ định
Chúng ta có thể lọc các nút theo khoá con chung bằng cách truyền khoá đó vào tham số orderBy. Ví dụ: để truy xuất tất cả khủng long có chiều cao lớn hơn 3, chúng ta có thể làm như sau:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'
Bất kỳ nút nào không có khoá con mà chúng ta đang lọc sẽ được sắp xếp với giá trị
null. Để biết thông tin chi tiết về cách sắp xếp dữ liệu, hãy xem phần Cách sắp xếp dữ liệu.
Firebase cũng hỗ trợ các truy vấn được sắp xếp theo các phần tử con được lồng sâu, thay vì chỉ các phần tử con ở một cấp. Điều này hữu ích nếu bạn có dữ liệu được lồng sâu như sau:
{
"lambeosaurus": {
"dimensions": {
"height" : 2.1,
"length" : 12.5,
"weight": 5000
}
},
"stegosaurus": {
"dimensions": {
"height" : 4,
"length" : 9,
"weight" : 2500
}
}
}Để truy vấn chiều cao ngay bây giờ, chúng ta sử dụng đường dẫn đầy đủ đến đối tượng thay vì một khoá duy nhất:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="dimensions/height"&startAt=3&print=pretty'
Truy vấn chỉ có thể lọc theo một khoá tại một thời điểm. Việc sử dụng tham số orderBy nhiều
lần trên cùng một yêu cầu sẽ gây ra lỗi.
Lọc theo khoá
Chúng ta cũng có thể lọc các nút theo khoá của chúng bằng cách sử dụng tham số orderBy="$key". Ví dụ sau đây truy xuất tất cả khủng long có tên bắt đầu bằng chữ cái a đến m:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="a"&endAt="m"&print=pretty'
Lọc theo giá trị
Chúng ta có thể lọc các nút theo giá trị của khoá con bằng cách sử dụng tham số orderBy="$value". Giả sử khủng long đang tham gia cuộc thi thể thao khủng long và chúng ta đang theo dõi
điểm số của chúng theo định dạng sau:
{
"scores": {
"bruhathkayosaurus": 55,
"lambeosaurus": 21,
"linhenykus": 80,
"pterodactyl": 93,
"stegosaurus": 5,
"triceratops": 22
}
}Để truy xuất tất cả khủng long có điểm số cao hơn 50, chúng ta có thể đưa ra yêu cầu sau:
curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&startAt=50&print=pretty'
Hãy xem phần Cách sắp xếp dữ liệu để biết giải thích về
cách null, boolean, chuỗi và đối tượng được sắp xếp khi sử dụng
orderBy="$value".
Lọc phức tạp
Chúng ta có thể kết hợp nhiều tham số để tạo các truy vấn phức tạp hơn.
Truy vấn giới hạn
Các tham số limitToFirst và limitToLast được dùng để đặt số lượng tối đa các phần tử con mà bạn muốn nhận dữ liệu. Nếu chúng ta đặt giới hạn là 100, thì chúng ta sẽ chỉ
nhận được tối đa 100 phần tử con phù hợp. Nếu chúng ta có ít hơn 100 tin nhắn được lưu trữ trong cơ sở dữ liệu, thì chúng ta sẽ nhận được mọi phần tử con. Tuy nhiên, nếu chúng ta có hơn 100 tin nhắn, thì chúng ta sẽ chỉ
nhận được dữ liệu cho 100 tin nhắn trong số đó. Đây sẽ là 100 tin nhắn đầu tiên được sắp xếp nếu chúng ta đang
sử dụng limitToFirst hoặc 100 tin nhắn cuối cùng được sắp xếp nếu chúng ta đang sử dụng
limitToLast.
Sử dụng cơ sở dữ liệu về các sự kiện khủng long và orderBy, chúng ta có thể tìm thấy 2
con khủng long nặng nhất:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="weight"&limitToLast=2&print=pretty'
Tương tự, chúng ta có thể tìm thấy 2 con khủng long ngắn nhất bằng cách sử dụng limitToFirst:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&limitToFirst=2&print=pretty'
Chúng ta cũng có thể thực hiện các truy vấn giới hạn bằng orderBy="$value". Nếu chúng ta muốn tạo bảng xếp hạng với 3 đối thủ thể thao khủng long có điểm số cao nhất, chúng ta có thể làm như sau:
curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&limitToLast=3&print=pretty'
Truy vấn phạm vi
Việc sử dụng startAt, endAt và equalTo cho phép chúng ta chọn
điểm bắt đầu và điểm kết thúc tuỳ ý cho các truy vấn. Ví dụ: nếu muốn tìm tất cả
khủng long cao ít nhất 3 mét, chúng ta có thể kết hợp orderBy và
startAt:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'
Chúng ta có thể sử dụng endAt để tìm tất cả khủng long có tên đứng trước Pterodactyl
theo thứ tự từ vựng:
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&endAt="pterodactyl"&print=pretty'
Chúng ta có thể kết hợp startAt và endAt để giới hạn cả hai đầu của truy vấn.
Ví dụ sau đây tìm tất cả khủng long có tên bắt đầu bằng chữ cái "b":
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="b"&endAt="b\uf8ff"&print=pretty'
Truy vấn phạm vi cũng hữu ích khi bạn cần phân trang dữ liệu.
Đang kết hợp
Chúng ta có thể kết hợp tất cả các kỹ thuật này để tạo các truy vấn phức tạp. Ví dụ: có thể bạn muốn tìm tên của tất cả khủng long có chiều cao nhỏ hơn hoặc bằng loài khủng long yêu thích của chúng ta, Stegosaurus:
MY_FAV_DINO_HEIGHT=`curl "https://dinosaur-facts.firebaseio.com/dinosaurs/stegosaurus/height.json"`
curl "https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy=\"height\"&endAt=${MY_FAV_DINO_HEIGHT}&print=pretty"
Cách sắp xếp dữ liệu
Phần này giải thích cách sắp xếp dữ liệu của bạn khi sử dụng từng tham số trong số 3 tham số lọc.
orderBy
Khi sử dụng orderBy với tên của khoá con, dữ liệu chứa khoá con đã chỉ định
sẽ được sắp xếp như sau:
-
Các phần tử con có giá trị
nullcho khoá con đã chỉ định sẽ xuất hiện trước. -
Các phần tử con có giá trị
falsecho khoá con đã chỉ định sẽ xuất hiện tiếp theo. Nếu nhiều phần tử con có giá trịfalse, thì các phần tử con đó sẽ được sắp xếp theo thứ tự từ vựng theo khoá. -
Các phần tử con có giá trị
truecho khoá con đã chỉ định sẽ xuất hiện tiếp theo. Nếu nhiều phần tử con có giá trịtrue, thì các phần tử con đó sẽ được sắp xếp theo thứ tự từ vựng theo khoá. - Các phần tử con có giá trị số sẽ xuất hiện tiếp theo, được sắp xếp theo thứ tự tăng dần. Nếu nhiều phần tử con có cùng giá trị số cho nút con đã chỉ định, thì các phần tử con đó sẽ được sắp xếp theo khoá.
- Các chuỗi sẽ xuất hiện sau các số và được sắp xếp theo thứ tự từ vựng tăng dần. Nếu nhiều phần tử con có cùng giá trị cho nút con đã chỉ định, thì các phần tử con đó sẽ được sắp xếp theo thứ tự từ vựng theo khoá.
- Các đối tượng sẽ xuất hiện cuối cùng và được sắp xếp theo thứ tự từ vựng theo khoá theo thứ tự tăng dần.
orderBy="$key"
Khi sử dụng tham số orderBy="$key" để sắp xếp dữ liệu, dữ liệu sẽ được trả về
theo thứ tự tăng dần theo khoá như sau. Xin lưu ý rằng khoá chỉ có thể là chuỗi.
- Các phần tử con có khoá có thể được phân tích cú pháp dưới dạng số nguyên 32 bit sẽ xuất hiện trước, được sắp xếp theo thứ tự tăng dần.
- Các phần tử con có giá trị chuỗi làm khoá sẽ xuất hiện tiếp theo, được sắp xếp theo thứ tự từ vựng tăng dần.
orderBy="$value"
Khi sử dụng tham số orderBy="$value" để sắp xếp dữ liệu, các phần tử con sẽ được
sắp xếp theo giá trị của chúng. Tiêu chí sắp xếp giống như dữ liệu được sắp xếp theo khoá con,
ngoại trừ việc giá trị của nút được sử dụng thay vì giá trị của khoá con đã chỉ định.
orderBy="$priority"
Khi sử dụng tham số orderBy="$priority" để sắp xếp dữ liệu, thứ tự của các phần tử con
sẽ được xác định theo mức độ ưu tiên và khoá của chúng như sau. Xin lưu ý rằng giá trị ưu tiên
chỉ có thể là số hoặc chuỗi.
- Các phần tử con không có mức độ ưu tiên (mặc định) sẽ xuất hiện trước.
- Các phần tử con có số làm mức độ ưu tiên sẽ xuất hiện tiếp theo. Các phần tử con đó được sắp xếp theo số theo mức độ ưu tiên, từ nhỏ đến lớn.
- Các phần tử con có chuỗi làm mức độ ưu tiên sẽ xuất hiện cuối cùng. Các phần tử con đó được sắp xếp theo thứ tự từ vựng theo mức độ ưu tiên.
- Bất cứ khi nào 2 phần tử con có cùng mức độ ưu tiên (kể cả không có mức độ ưu tiên), thì các phần tử con đó sẽ được sắp xếp theo khoá. Các khoá số sẽ xuất hiện trước (được sắp xếp theo số), tiếp theo là các khoá còn lại (được sắp xếp theo thứ tự từ vựng ).
Để biết thêm thông tin về mức độ ưu tiên, hãy xem tài liệu tham khảo về API.
Truyền trực tuyến từ API REST
Các điểm cuối Firebase REST hỗ trợ giao thức EventSource / Sự kiện do máy chủ gửi, giúp bạn dễ dàng truyền trực tuyến các thay đổi đến một vị trí duy nhất trong cơ sở dữ liệu Firebase.
Để bắt đầu truyền trực tuyến, chúng ta cần làm như sau:
-
Đặt tiêu đề Chấp nhận của ứng dụng khách thành
text/event-stream - Tuân thủ các lượt chuyển hướng HTTP, đặc biệt là mã trạng thái HTTP 307
-
Thêm tham số truy vấn
authnếu vị trí cơ sở dữ liệu Firebase yêu cầu quyền đọc
Đổi lại, máy chủ sẽ gửi các sự kiện được đặt tên khi trạng thái của dữ liệu tại URL được yêu cầu thay đổi. Cấu trúc của các thông báo này tuân theo giao thức EventSource:
event: event name data: JSON encoded data payload
Máy chủ có thể gửi các sự kiện sau:
| đặt | Dữ liệu được mã hoá bằng JSON sẽ là một đối tượng có 2 khoá: đường dẫn và dữ liệu Đường dẫn trỏ đến một vị trí tương ứng với URL yêu cầu Ứng dụng khách sẽ thay thế tất cả dữ liệu tại vị trí đó trong bộ nhớ đệm bằng dữ liệu được cung cấp trong thông báo |
| bản vá | Dữ liệu được mã hoá bằng JSON sẽ là một đối tượng có 2 khoá: đường dẫn và dữ liệu Đường dẫn trỏ đến một vị trí tương ứng với URL yêu cầu Đối với mỗi khoá trong dữ liệu, ứng dụng khách sẽ thay thế khoá tương ứng trong bộ nhớ đệm bằng dữ liệu cho khoá đó trong thông báo |
| keep-alive | Dữ liệu cho sự kiện này là giá trị rỗng, không cần thực hiện hành động nào |
| hủy | Dữ liệu cho sự kiện này là giá trị rỗng Sự kiện này sẽ được gửi nếu Firebase Realtime Database Security Rules khiến việc đọc tại vị trí được yêu cầu không còn được phép nữa |
| auth_revoked | Dữ liệu cho sự kiện này là một chuỗi cho biết rằng thông tin xác thực đã hết hạn Sự kiện này sẽ được gửi khi tham số xác thực được cung cấp không còn hợp lệ nữa |
Dưới đây là ví dụ về một tập hợp các sự kiện mà máy chủ có thể gửi:
// Set your entire cache to {"a": 1, "b": 2} event: put data: {"path": "/", "data": {"a": 1, "b": 2}} // Put the new data in your cache under the key 'c', so that the complete cache now looks like: // {"a": 1, "b": 2, "c": {"foo": true, "bar": false}} event: put data: {"path": "/c", "data": {"foo": true, "bar": false}} // For each key in the data, update (or add) the corresponding key in your cache at path /c, // for a final cache of: {"a": 1, "b": 2, "c": {"foo": 3, "bar": false, "baz": 4}} event: patch data: {"path": "/c", "data": {"foo": 3, "baz": 4}}
Nếu bạn đang sử dụng Go, hãy xem Firego, một trình bao bọc bên thứ ba xung quanh API Truyền trực tuyến và REST của Firebase.