【问题标题】:Firestore - Subcollections SwiftFirestore - 子集合 Swift
【发布时间】:2018-05-03 21:16:59
【问题描述】:

所以我正在尝试学习一些 Firestore 的基本功能,并在 YouTube 上观看了解释 CRUD 操作的“Kilo Locos”视频。我想采用他的代码方法并从中创建子集合。基本上,我如何添加一个集合并使“用户”集合成为这个新集合的子集合。非常感谢任何帮助,非常感谢!

这里是下载项目的链接: https://kiloloco.com/courses/youtube/lectures/3944217

FireStore 服务

import Foundation
import Firebase
import FirebaseFirestore

class FIRFirestoreService {
    
    private init() {}
    static let shared = FIRFirestoreService()
    
    func configure() {
        FirebaseApp.configure()
    }
    
    private func reference(to collectionReference: FIRCollectionReference) -> CollectionReference {
        return Firestore.firestore().collection(collectionReference.rawValue)
    }
    
    func create<T: Encodable>(for encodableObject: T, in collectionReference: FIRCollectionReference) {
        do {
            let json = try encodableObject.toJson(excluding: ["id"])
            reference(to: collectionReference).addDocument(data: json)
            
        } catch {
            print(error)
        }
    }
    
    func read<T: Decodable>(from collectionReference: FIRCollectionReference, returning objectType: T.Type, completion: @escaping ([T]) -> Void) {
        
        reference(to: collectionReference).addSnapshotListener { (snapshot, _) in
            
            guard let snapshot = snapshot else { return }
            
            do {
                
                var objects = [T]()
                for document in snapshot.documents {
                    let object = try document.decode(as: objectType.self)
                    objects.append(object)
                }
                
                completion(objects)
                
            } catch {
                print(error)
            }
        }
    }
    
    func update<T: Encodable & Identifiable>(for encodableObject: T, in collectionReference: FIRCollectionReference) {
        
        do {
            
            let json = try encodableObject.toJson(excluding: ["id"])
            guard let id = encodableObject.id else { throw MyError.encodingError }
            reference(to: collectionReference).document(id).setData(json)
            
        } catch {
            print(error)
        }
    }
    
    func delete<T: Identifiable>(_ identifiableObject: T, in collectionReference: FIRCollectionReference) {
        
        do {
            
            guard let id = identifiableObject.id else { throw MyError.encodingError }
            reference(to: collectionReference).document(id).delete()
            
        } catch {
            print(error)
        }
    }
}

FIRCollectionReference

import Foundation

enum FIRCollectionReference: String {
    case users
}

用户

import Foundation

protocol Identifiable {
    var id: String? { get set }
}

struct User: Codable, Identifiable {
    var id: String? = nil
    let name: String
    let details: String
    
    init(name: String, details: String) {
        self.name = name
        self.details = details
    }
}

可编码扩展

import Foundation

enum MyError: Error {
    case encodingError
}

extension Encodable {
    
    func toJson(excluding keys: [String] = [String]()) throws -> [String: Any] {
        
        let objectData = try JSONEncoder().encode(self)
        let jsonObject = try JSONSerialization.jsonObject(with: objectData, options: [])
        guard var json = jsonObject as? [String: Any] else { throw MyError.encodingError }
        
        for key in keys {
            json[key] = nil
        }
        
        return json
        
    }
    
}

快照扩展

import Foundation
import FirebaseFirestore

extension DocumentSnapshot {
    
    func decode<T: Decodable>(as objectType: T.Type, includingId: Bool = true) throws  -> T {
        
        var documentJson = data()
        if includingId {
            documentJson!["id"] = documentID
        }
        
        let documentData = try JSONSerialization.data(withJSONObject: documentJson!, options: [])
        let decodedObject = try JSONDecoder().decode(objectType, from: documentData)
        
        return decodedObject
    }
}

【问题讨论】:

  • 添加您的代码,而不是指向您的代码图片的链接。另外,您的问题不够清晰。
  • 您好 Picciano,请参阅修改后的问题。非常感谢!

标签: swift firebase collections google-cloud-firestore


【解决方案1】:

Firestore 结构不能将集合作为其他集合的子级。

您的问题的答案(如何添加一个集合并使“用户”集合成为这个新集合的子集合?)是您不能。相反,您必须在这两个集合之间放置一个文档。


Read this for more information.

上面写着:Notice the alternating pattern of collections and documents. Your collections and documents must always follow this pattern. You cannot reference a collection in a collection or a document in a document.

【讨论】:

  • 嗨 AgRizzo,谢谢您的回复,我知道这一点,我的想法是在第一个集合中添加一个自动 ID,然后将子集合嵌套在这个自动 ID 中?这肯定有可能吗?
  • 如果您知道,您应该使用 Firestore 术语 collectiondocument,因为即使现在您说的是 auto ID i> 这并不意味着什么。您是说将文档添加到顶级集合,然后在该文档下添加 user 集合吗?如果是,那么
  • 对不起!!是的,这就是我的意思,为顶级集合的文档分配一个自动 ID,然后在该文档下拥有集合“用户”。你知道我怎么能用上面的代码方法做到这一点吗?谢谢你的帮助!!
猜你喜欢
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2019-07-25
  • 2019-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多