Firebaseで以下のような構造を持つデータがあった場合、ref.child("users").observe(.value, ...)
とした場合に変更を検知して帰ってくるsnapshotがどんな値か分からなかった。やりたいことはユーザーの子の子である注文情報が追加されたら、それが誰であってもタイムラインに表示をさせたい。

公式リファレンスでは.value
を使うときはsnapshot.children
をforで回して個別の子にアクセスできるよと書いているが、何のこっちゃよく分からない。なので毎回childをprintすることで、どんな値なのか調べてみた。
func startObservingDatabase () {
databaseHandle = ref.child("users").observe(.value, with: { [weak self] (snapshot) in
guard let strongSelf = self else { return }
strongSelf.orders.removeAll()
print("snapshot: \(snapshot)")
for child in snapshot.children {
print("snapshot.child: \(child)")
guard let userSnapshot = child as? DataSnapshot else { return }
for child in userSnapshot.children {
print("userSnapshot.child:\(child)")
guard let ordersSnapshot = child as? DataSnapshot else { return }
for child in ordersSnapshot.children {
print("ordersSnapshot.child:\(child)")
guard let orderSnapshot = child as? DataSnapshot else { return }
strongSelf.orders.append(orderSnapshot)
}
}
}
strongSelf.orders.reverse()
strongSelf.tableView.reloadData()
})
}
これでRunして、一番下の子ノードであるorderデータを追加すると以下のようにusersノードのデータ全部のsnapshotが返ってくる。
snapshot: Snap (users) {
snapshot.child: Snap (zxzGLeLBJvguP7TDMMtc7zDfqdO2) {
userSnapshot.child:Snap (orders) {
ordersSnapshot.child:Snap (17065026d06aa5b3) {
ordersSnapshot.child:Snap (17067ac197c29929) {
ordersSnapshot.child:Snap (1706a288c50dd2d4) {
ordersSnapshot.child:Snap (17089ff731c2f382) {
ordersSnapshot.child:Snap (1709e0d81897c5bb) {
なので子供の子供の・・・と紐解いてやって出てきた注文データをappendすると、新規で追加されたデータ以外も全てordersに追加されてデータが重複するため、一旦は変更を検知したらプロパティのordersをremoveAll()し、そして新たに全注文データをセットしてreloadData()すると言うエンジニアが発狂しそうなやり方をとった(笑)。
これtableViewのリロード何回走るんやろう…。Firebase詳しいSwiftエンジニアさん誰か助けて。