【发布时间】:2020-07-25 12:50:37
【问题描述】:
在我的项目中,我使用 firebase Cloud Firestore 来实现类似“Facebook”的系统来请求和确认朋友。
在我的应用中,一些用户是管理员,一些只是普通用户。
只有普通用户才能搜索和添加管理员,以便加入管理员安排的某些特定活动。
下面是我在 Cloud Firestore 中的数据:
每个用户都有待处理和确认的朋友的收藏。
我正在使用视图为每个用户列出所有待定和确认的朋友
使用 firebase 的 .addSnapshotListener {} 每次确认好友和待处理好友发生更改时,我都会使用以下函数进行检查,并在 2 个 @Published 数组中发布更改,pendingFriendsADMIN = [UserMOdel] 和 confirmFriendADMIN = [用户模型]
func userUpdateFriendUser(userInfo: UserModel){
db.collection("userUser").document(userInfo.email).collection("pendingFriends")
.addSnapshotListener(includeMetadataChanges: false) { documentSnapshot, error in
self.pendingFriendsUSER = []
guard let documents = documentSnapshot?.documents else {
print("Error fetching documents: \(String(describing: error?.localizedDescription))")
return
}
var i = 0
for doc in documents {
debugPrint("inizio il ciclo pending user\(i)")
let idUser = doc["userID"] as? String ?? "no ID"
self.downloadImageForAdmin(userID: idUser) { (urlImage) in
let userPending = UserModel(name: "", surname: "" ,username: "", email: "", userID: "", adminLevel: "", immagine: urlImage!, position: "centro", position2: "sx", vote: 0)
userPending.name = doc["name"] as? String ?? "NA name"
userPending.surname = doc["surname"] as? String ?? "NA surname"
userPending.adminLevel = doc["adminLevel"] as? String ?? "NA admin"
userPending.email = doc["email"] as? String ?? "NA email"
userPending.username = doc["username"] as? String ?? "NA username"
userPending.userID = doc["userID"] as? String ?? "NA id"
userPending.position = doc["position"] as? String ?? "na position"
userPending.position2 = doc["position2"] as? String ?? "na position"
userPending.vote = doc["vote"] as? Int ?? 0
self.pendingFriendsUSER.append(userPending)
i = i+1
debugPrint("finito ciclo pending")
}
}
}
db.collection("userUser").document(userInfo.email).collection("confirmedFriend")
.addSnapshotListener (includeMetadataChanges: false){ documentSnapshot, error in
self.confirmedFriendUSER = []
guard let documents = documentSnapshot?.documents else {
print("Error fetching documents: \(String(describing: error?.localizedDescription))")
return
}
for doc in documents {
debugPrint("inizio il ciclo confirm user \(i)")
let idUser = doc["userID"] as? String ?? "no ID"
self.downloadImageForAdmin(userID: idUser) { (urlImage) in
let userConfirm = UserModel(name: "", surname: "" ,username: "", email: "", userID: "", adminLevel: "", immagine: urlImage!, position: "centro", position2: "sx", vote: 0)
userConfirm.name = doc["name"] as? String ?? "NA name"
userConfirm.surname = doc["surname"] as? String ?? "NA surname"
userConfirm.adminLevel = doc["adminLevel"] as? String ?? "NA admin"
userConfirm.email = doc["email"] as? String ?? "NA email"
userConfirm.username = doc["username"] as? String ?? "NA username"
userConfirm.userID = doc["userID"] as? String ?? "NA id"
userConfirm.position = doc["position"] as? String ?? "na position"
userConfirm.position2 = doc["position2"] as? String ?? "na position"
userConfirm.vote = doc["vote"] as? Int ?? 0
self.confirmedFriendUSER.append(userConfirm)
}
}
}
}
类似的方法也用于列出userFriendList上的变化。
用户,可以通过邮件搜索管理员,并向他发送好友请求(见下文)
用户使用以下函数发送好友请求: 简单地说,我在用户的待处理朋友上写了管理员电子邮件,在管理员待处理朋友中写了用户电子邮件
func sendFriendRequest(userInfo: UserModel, userToRequest: UserModel, closure: @escaping warning){
// check if reuqest already sent
self.db.collection("userAdmin").document(userToRequest.email).collection("confirmedFriend").whereField("email", isEqualTo: userInfo.email).getDocuments() { (queryResult, err) in
if let err = err {
debugPrint("unable to get data , friend alrady request\(err)")
} else {
if queryResult!.documents.count > 0 {
debugPrint("siete gia amici") // mettere warning
let warning = true
closure(warning)
return
} else {
// if request never sent, metto user nella lista dell admin pending
self.db.collection("userAdmin").document(userToRequest.email).collection("pendingFriends").document(userInfo.email).setData([
"username": userInfo.username,
"email" : userInfo.email,
"userID" : userInfo.userID,
"adminLevel": userInfo.adminLevel,
"name":userInfo.name,
"surname":userInfo.surname,
"position": userInfo.position,
"position2": userInfo.position2,
"vote": userInfo.vote
], merge: false) { (err) in
self.db.collection("userUser").document(userInfo.email).collection("pendingFriends").document(userToRequest.email).setData([
"username": userToRequest.username,
"email" : userToRequest.email,
"userID" : userToRequest.userID,
"adminLevel": userToRequest.adminLevel,
"name":userToRequest.name,
"surname":userToRequest.surname,
"position": userToRequest.position,
"position2": userToRequest.position2,
"vote": userToRequest.vote
], merge: false)
}
// metto sulla mia pending request
}
}
}
}
这里的问题... 有时,并非总是在我向朋友管理员发送请求时,.addSnapshotListener 会重复更改,正如您从第三张图片中看到的那样,有 2 次相同的待处理朋友。
如果我退出视图并返回,待处理的朋友是正确的。
这里是我的 AdminFriendRequest 的代码:查看
import SwiftUI
import URLImage
struct AdminFriendRequest: View {
@Binding var dismissView : Bool
@ObservedObject var dm : DataManager
@Binding var meInfo: UserModel?
var body: some View {
VStack{
fakebar
Spacer()
List{
HStack {
Image(systemName: "person.2")
Text("Pending friends request:")
}.font(.headline)
.foregroundColor(.blue)
ForEach(dm.pendingFriendsADMIN) { friend in
HStack{
if friend.immagine == nil{
Image(systemName: "person")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.clipShape(Circle())
} else {
URLImage(friend.immagine!) { proxy in
proxy.image
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.clipShape(Circle())
}
}
Text(friend.username)
Spacer()
Image(systemName: "checkmark.circle")
}
.onTapGesture {
if self.meInfo != nil {
self.dm.tapToConfirmFriend(me: self.meInfo!, friendToConfirm: friend) { (isFriendConfirm) in
debugPrint("is friend confirm \(isFriendConfirm)")
}
}
}
}
if dm.pendingFriendsADMIN.isEmpty {
Text("No friend request yet").font(.caption)
}
HStack {
Image(systemName: "person.3")
Text("Friends:")
}.font(.headline)
.foregroundColor(.blue)
ForEach(dm.confirmedFriendADMIN) { friend in
HStack{
if friend.immagine == nil{
Image(systemName: "person")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.clipShape(Circle())
} else {
URLImage(friend.immagine!) { proxy in
proxy.image
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.clipShape(Circle())
}
}
Text(friend.username)
Spacer()
Image(systemName: "checkmark.circle").foregroundColor(.green)
Button(action: {
self.dm.removeFriend(me: self.meInfo!, friendConfirm: friend)
}, label: {
Text("remove friend")
})
}.padding(.all)
}
}.padding(.trailing)
}
.onAppear {
self.dm.newListUpdateForAdmin(userInfo: self.meInfo!)
}
}
var fakebar: some View {
ZStack {
HStack {
Spacer()
Image(systemName: "chevron.compact.down")
.font(.system(size: 60))
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
Spacer()
}
HStack {
Spacer()
Button(action: {
self.dismissView.toggle()
}) {
Text("Close")
.fontWeight(.bold)
.foregroundColor(.white)
.padding(.horizontal)
}
}
}
.frame(height: 44)
.background(Color.green.padding(.top, -44))
}
}
我使用 onAppear 通过 .addSnapshotListener 触发列表更新
.onAppear {
self.dm.newListUpdateForAdmin(userInfo: self.meInfo!)
}
我不知道为什么...我使用 .addSnapshotListener 的方式是否正确? 或任何其他想法如何处理好友请求。很高兴改变我处理好友请求的方式。
谢谢
【问题讨论】:
标签: arrays firebase google-cloud-firestore swiftui