现在我在Firestore中开发这个应用程序,它可以在小组中共享照片。教我如何制作数据结构。我只知道使用用户和照片的数据结构。
- photo-1
- owner\_id
- url- photo-2
- owner\_id
- url- user-1
- user\_id
- user\_name- user-2
- user\_id
- user\_name当我想查询与userId匹配的照片时
Firestore.firestore().collection("Photos")
.whereField("owner_id", isEqualTo: userId)上面的这些可以告诉我们。
我有问题。如果我想添加能够看到共享图像的组,我应该如何使数据成为结构和查询。我想要的这个功能就像谷歌文档。它只能共享允许的用户。所以我认为这是群函数所用的。
请教我数据结构和查询。
发布于 2022-08-27 09:44:56
照片文档可以有一个允许的用户ids (或多个用户)数组。下面的方法在我的测试环境中有效。在PhotosViewModel中,我们有一个fetchPermittedPhotos函数,它处理的是当前用户仅仅获得了他可以看到的照片。
模型
用户
在本例中,我们从当前用户获取uid,该用户已通过firebase身份验证(Auth.auth().currentUser!.uid).登录。getCurrentUser函数搜索具有特定文档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
}
}ViewModels
UsersViewModel
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")
}
}
}
}PhotosViewModel
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")
}
}
}https://stackoverflow.com/questions/73508845
复制相似问题