讀取 Cloud Firestore 的 database

官方文件

範例 1

collection() 裡可傳入 collection 的名字,因此我們用 db.collection("songs") 取得 songs collection,然後再呼叫 function getDocuments 取得它底下所有的 documents。 (記得要 import Firebase)

let db = Firestore.firestore()db.collection("songs").getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.data())      }   }}

document 的型別為 QueryDocumentSnapshot,利用它的 data() 可取得 dictionary 型別的資料。

比方以下寫法可取得歌名。

let name = document.data()["name"]

結果

["singer": 薛之謙, "rate": 3, "name": 演員]["singer": 田馥甄, "name": 小幸運, "rate": 4]["singer": 周興哲, "name": 你好不好, "rate": 5]

ps: 當 getDocuments 找不到任何 document 時,可利用 querySnapshot.documents.count 是否為 0 判斷。

以 rate 排序,由小到大。

let db = Firestore.firestore()db.collection("songs").order(by: "rate").getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.data())      }   }}

結果

["name": 演員, "singer": 薛之謙, "rate": 3]["rate": 4, "singer": 田馥甄, "name": 小幸運]["rate": 5, "singer": 周興哲, "name": 你好不好]
let db = Firestore.firestore()db.collection("students").order(by: "height").order(by: "weight").getDocuments { (querySnapshot, error) in}

以 rate 排序,由大到小。

let db = Firestore.firestore()db.collection("songs").order(by: "rate", descending: true).getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.data())      }   }}

結果

["name": 你好不好, "rate": 5, "singer": 周興哲]["singer": 田馥甄, "name": 小幸運, "rate": 4]["singer": 薛之謙, "name": 演員, "rate": 3]

以 limit(to:) 指定抓取的數量。

db.collection("songs").order(by: "rate").limit(to: 2).getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.data())      }   }}

結果

["name": 演員, "rate": 3, "singer": 薛之謙]["name": 小幸運, "singer": 田馥甄, "rate": 4]

利用 whereField 設定 search 的條件。

let db = Firestore.firestore()db.collection("songs").whereField("singer", isEqualTo: "周興哲").getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {       for document in querySnapshot.documents {         print(document.data())      }   }}

結果

["name": 你好不好, "singer": 周興哲, "rate": 5]

範例 2

let db = Firestore.firestore()db.collection("music").document("周杰倫").getDocument { (document, error) in   if let document = document, document.exists {      print(document.documentID, document.data())   } else {      print("Document does not exist")   }}

結果

周杰倫 Optional(["gender": 男])
let db = Firestore.firestore()db.collection("music").document("周杰倫").collection("albums").getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.documentID)      }   }}

結果

葉惠美

利用 document 或 collection 路徑讀取

利用 collection 路徑讀取 documents

let db = Firestore.firestore()db.collection("music/周杰倫/albums").getDocuments { (querySnapshot, error) in   if let querySnapshot = querySnapshot {      for document in querySnapshot.documents {         print(document.documentID)      }   }}

結果

葉惠美

利用 document 路徑讀取 document

let db = Firestore.firestore()db.document("music/周杰倫").getDocument  { (document, error) in   if let document = document, document.exists {      print(document.documentID, document.data())   } else {      print("Document does not exist")   }}

結果

周杰倫 Optional(["gender": 男])

持續偵測 collection 下的 document 是否有新增,刪除,修改

一開始 addSnapshotListener 會先抓到 collection 下所有的 document, 因此 documentChanges 將包含所有的 document,type 則為 .added。之後 addSnapshotListener 的 closure 再被觸發時,documentChanges 將只包含新增,刪除或修改的 document。

let db = Firestore.firestore()db.collection("songs").addSnapshotListener { (querySnapshot, error) in   guard let querySnapshot = querySnapshot else {      return   }   querySnapshot.documentChanges.forEach({ (documentChange) in      if documentChange.type == .added {         print(documentChange.document.data())      }   })}

將偵測到的資料儲存到 array,顯示在表格上

class SongsTableViewController: UITableViewController {

var songs = [QueryDocumentSnapshot]()
override func viewDidLoad() {
super.viewDidLoad()
let db = Firestore.firestore()
db.collection("songs").order(by: "rate").addSnapshotListener { (querySnapshot, error) in
guard let querySnapshot = querySnapshot else {
return
}

self.songs = querySnapshot.documents
self.tableView.reloadData()
}
}

自訂型別儲存 Firebase 抓取的資料

範例

struct Song {
var name: String
var singer: String
var rate: Int
var youtube: URL?
}
extension Song {
init(dic: [String: Any]) {
name = dic["name"] as? String ?? "街角的祝福"
singer = dic["singer"] as? String ?? "peter pan"
rate = dic["rate"] as? Int ?? 1
if let urlString = dic["youtube"] as? String {
youtube = URL(string: urlString)
}
}
}
class SongsTableViewController: UITableViewController {    var songs = [Song]()

在 SongsTableViewController 裡定義 function getSongs。

方法一: 用 map 將 Firebase 的資料轉換成自訂型別。

func getSongs() {
let db = Firestore.firestore()
db.collection("songs").order(by: "rate").addSnapshotListener { (querySnapshot, error) in
guard let querySnapshot = querySnapshot else {
return
}

self.songs = querySnapshot.documents.map {
Song(dic: $0.data())
}


self.tableView.reloadData()
}
}

方法二: 用 forEach 將 Firebase 的資料轉換成自訂型別。

querySnapshot.documents.forEach { (songDoc) in
let song = Song(dic: songDoc.data())
self.songs.append(song)
}

方法三: 用 for in 將 Firebase 的資料轉換成自訂型別。

for songDoc in querySnapshot.documents {
let song = Song(dic: songDoc.data())
self.songs.append(song)
}

分頁功能

彼得潘的 Swift iOS App 開發問題解答集

彼得潘和學生們在開發 iOS App 路上曾經解決的問題集

彼得潘的 iOS App Neverland

Written by

彼得潘的 Swift 程式設計入門,App程式設計入門作者,彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,http://apppeterpan.strikingly.com

彼得潘的 Swift iOS App 開發問題解答集

彼得潘和學生們在開發 iOS App 路上曾經解決的問題集

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade