【SwiftUI】Firestoreのデータを一覧表示する

先日Firestoreの初期設定をしました。

Firestoreで登録したデータをアプリで一覧表示するところまでやってみたので紹介します。

Firestoreで以下のように適当にデータを追加しておきます。

Swiftでデータを入れる構造体とクラスを作ります。

import Foundation
import FirebaseFirestore

struct Message: Identifiable {
    var id: String = UUID().uuidString
    var name: String
    var post: String
    var dateEvent: Date
    var dateString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy年M月d日 H時m分"
        return formatter.string(from: dateEvent)
    }
}

class ViewModel: ObservableObject {
    
    @Published var messages = [Message]()
    
    private var db = Firestore.firestore()
    
    func fetchData() {
        db.collection("messages").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                print("No documents")
                return
            }
            
            self.messages = documents.map { (queryDocumentSnapshot) -> Message in
                let data = queryDocumentSnapshot.data()
                let name = data["name"] as? String ?? ""
                let post = data["post"] as? String ?? ""
                let dateEvent = (data["time"] as? Timestamp)?.dateValue() ?? Date()
                return Message(name: name, post: post, dateEvent: dateEvent)
            }
        }
    }
}

SnapshotListenerを使うと、リアルタイムに更新ができる模様。便利。

追記:時間でソートするには以下のようにする

        db.collection("messages")
            .order(by: "time")
            .addSnapshotListener { (querySnapshot, error) in

取得したデータは以下のように表示してみる。

import SwiftUI
import FirebaseCore

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()
    
    var body: some View {
        NavigationView {
            List(viewModel.messages) { message in
                VStack(alignment: .leading) {
                    Text(message.post).font(.title)
                    Text("by " + message.name)
                    Text(message.dateString)
                }
            }.navigationBarTitle("Chat")
            .onAppear() {
                self.viewModel.fetchData()
            }
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

実行結果。

チャットアプリ

あとはアプリ側でチャットにメッセージを追加できるようにしたい。

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog