繁体   English   中英

在 Firestore 中如何制作数据结构以及如何查询它们

[英]In Firestore how to make Data structure and how to query them

现在我正在 Firestore 中开发可以分组分享照片的应用程序。 教我如何制作数据结构。 我只知道使用用户和照片的数据结构。

  • 相片

    • 照片1
      • owner_id
      • url
    • 照片2
      • owner_id
      • url
  • 用户

    • 用户 1
      • 用户身份
      • 用户名
    • 用户 2
      • 用户身份
      • 用户名

当我想查询与 userId 匹配的照片时

Firestore.firestore().collection("Photos")
    .whereField("owner_id", isEqualTo: userId)

以上这些可以告诉我们。

我有问题。 如果我想添加可以查看共享图像的组,我应该如何使数据成为结构和查询。 我想要的这个 function 就像谷歌文档。 它只能共享允许的用户。 所以我认为这是由 function 组使用的。

请教我数据结构和查询。

照片文档可以有一组允许的用户 ID(或用户)。 以下方法在我的测试环境中有效。 在 PhotosViewModel 中,我们有一个 fetchPermittedPhotos function,它处理当前用户刚刚获得他有权查看的照片。

楷模

用户

在此示例中,我们从通过 firebase 身份验证( Auth.auth().currentUser..uid )登录的当前用户获取 uid。 getCurrentUser function 搜索具有特定文档 id 的文档,这里它再次使用当前用户的 uid。 这意味着,(新)用户 id 必须与 uid 相同。 类似于取照片时的权限处理。 该数组包含从Auth.auth().currentUser..uid获取的 uid 列表。 如果你不想这样,你必须相应地调整你的代码。

struct User: Codable, Identifiable, Hashable {

    var id: String?
    var name: String

    init(name: String, id: String?) {
        self.id = id
        self.name = name
    }

    init?(document: DocumentSnapshot) {
        let data = document.data()
        let name = data!["name"] as? String ?? ""

        id = document.documentID
        self.name = name
    }

    enum CodingKeys: String, CodingKey {
        case id
        case name
    }
}

扩展用户:可比 {

static func == (lhs: User, rhs: User) -> Bool {
    return lhs.id == rhs.id
}

static func < (lhs: User, rhs: User) -> Bool {
    return lhs.name < rhs.name
}

}

照片

struct Photo: Codable, Identifiable, Hashable {
    
    var id: String?
    var ownerUid: String
    var imageUrl: String
    var permittedUids: [String]
    
    init(ownerUid: String, imageUrl: String, permittedUids: [String], id: String = UUID().uuidString) {
        self.id = id
        self.ownerUid = ownerUid
        self.imageUrl = imageUrl
        self.permittedUids = permittedUids
    }
    
    init?(document: DocumentSnapshot) {
        let data = document.data()
        let ownerUid = data!["ownerUid"] as? String ?? ""
        let imageUrl = data!["imageUrl"] as? String ?? ""
        let permittedUids = data!["permittedUids"] as? [String] ?? []
        
        id = document.documentID
        self.ownerUid = ownerUid
        self.imageUrl = imageUrl
        self.permittedUids = permittedUids
    }
    
    enum CodingKeys: String, CodingKey {
        case id
        case ownerUid
        case imageUrl
        case permittedUids
    }
}

extension Photo: Comparable {
    
    static func == (lhs: Photo, rhs: Photo) -> Bool {
        return lhs.id == rhs.id
    }
    
    static func < (lhs: Photo, rhs: Photo) -> Bool {
        return lhs.ownerUid < rhs.ownerUid
    }
}

视图模型

用户视图模型

class UsersViewModel: ObservableObject {
    
    let db = Firestore.firestore()
    
    @Published var user: User?
    
    func fetchCurrentUser(_ completion: @escaping (Bool, String) ->Void) {
        guard let uid = Auth.auth().currentUser?.uid else {
            completion(false, "Could not find firebase uid")
            return
        }
        
        let docRef = self.db.collection("users").document(uid)
        docRef.getDocument { (document, error) in
            if let document = document, document.exists {
                self.user = User(document: document)
                completion(true, "User set up from Firestore db")
            } else {
                completion(false, "User document not found")
            }
        }
    }
}

照片视图模型

class PhotosViewModel: ObservableObject {
    
    let db = Firestore.firestore()
    let storage = Storage.storage()
    
    @Published var allphotos = [Photo]()
    @Published var permittedphotos = [Photo]()
    
    func addNewPhoto(photo: Photo, completion: @escaping (Bool, String)->Void) {
        do {
            try db.collection("photos").document(photo.id!).setData(from: photo) { _ in
                completion(true, "Photo added to Firestore")
            }
        } catch let error {
            print("Error writing photo to Firestore: \(error)")
            completion(false, "Error writing city to Firestore: \(error)")
        }
    }
    
    func fetchAllPhotos(_ completion: @escaping (Bool, String) ->Void) {
        self.allphotos.removeAll()
        db.collection("photos").addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                completion(true, "No documents")
                return
            }
            
            self.allphotos = documents.map { queryDocumentSnapshot -> Photo in
                return Photo(document: queryDocumentSnapshot)!
            }
            completion(true, "Data fetched")
        }
    }
    
    func fetchPermittedPhotos(_ completion: @escaping (Bool, String) ->Void) {
        
        guard let uid = Auth.auth().currentUser?.uid else {
            completion(false, "Could not find firebase uid")
            return
        }
        
        self.permittedphotos.removeAll()
        db.collection("photos").whereField("permittedUids", arrayContains: uid).addSnapshotListener { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                completion(true, "No documents")
                return
            }
            
            self.permittedphotos = documents.map { queryDocumentSnapshot -> Photo in
                return Photo(document: queryDocumentSnapshot)!
            }
            completion(true, "Data fetched")
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM