我的应用程序要求您至少关注四个人(或者按钮说“关注至少4个朋友”),以便开始回答关于您所关注的人的多项选择风格问答。现在,每当用户关注某人时,它就会在firebase上更新,但他们关注的人不会在MCQ / Q&A页面上实时显示,除非我从头开始运行该应用程序。
如何让它实时更新而不必从头开始重新运行?
更新:
我已将之前的observeSingleEvent函数更改为带有DataEventType.value的observe函数,并且它比以前更好,因为当我关注和取消关注人员时它会更新,但仅当用户有超过4个关注者时才会更新。
现在,如果我取消关注低于4个人,它会显示“至少跟随4个朋友”,但是当我追回到4个或更多个按钮时,按钮会调用4个随机用户,但冻结并且无法按下。
此外,当我尝试在底部为两个观察功能添加解除功能时 - 它会发出错误并且不会让我进入页面
这是更新的代码(我希望我正确解释并抱歉,如果它看起来像一个愚蠢的问题,我感谢任何帮助/解释) - 在此先感谢:)
在viewDidLoad中调用的函数是:
var ref: DatabaseReference = Database.database().reference()
var currNames: [String] = []
var currIds: [String] = []
let imageViewA = UIImageView()
let imageViewB = UIImageView()
let imageViewC = UIImageView()
let imageViewD = UIImageView()
func getFourRandomNodesAndPrintUserName() {
self.currNames = []
self.currIds = []
var myKeyArray = [String]()
guard let uid = Auth.auth().currentUser?.uid else {
return
}
let ref = self.ref.child("following").child(uid) //retreives all nodes in the following node
ref.observe(DataEventType.value, with: { (snapshot) in
print(snapshot.children.allObjects)
for child in snapshot.children { //build the array of keys
let snap = child as! DataSnapshot
let key = snap.key
myKeyArray.append(key)
}
var randomKeyArray = [String]()
let numFollowers = min(4, myKeyArray.count)
for _ in 0..<numFollowers { //will iterate four times
let count = myKeyArray.count //get the number of elements
let randomInt = Int.random(in: 0..<count) //get a random index for the array
let randomUserKey = myKeyArray[randomInt]
randomKeyArray.append(randomUserKey)
myKeyArray.remove(at: randomInt) //remove that object so it's not selected again
}
let numberOfKeys = randomKeyArray.count
var namesRemaining = numberOfKeys
var names = [String]()
var namesWithUrl = [String : String]()
var profileImages = [String]()
for i in 0..<numberOfKeys {
let thisUserKey = randomKeyArray[i]
let userRef = self.ref.child("users").child(thisUserKey)
userRef.observeSingleEvent(of: .value, with: { snapshot in
let name = snapshot.childSnapshot(forPath: "fullname").value as! String
let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String
print(name)
print(profileImageUrl)
namesRemaining -= 1
names.append(name)
profileImages.append(profileImageUrl)
namesWithUrl[name] = profileImageUrl
self.currIds.append(thisUserKey)
if numFollowers <= 3 {
self.optionA.setTitle("Follow\nat least\n4 friends!", for: .normal)
self.optionA.isEnabled = false
self.optionB.setTitle("Follow\nat least\n4 friends!", for: .normal)
self.optionB.isEnabled = false
self.optionC.setTitle("Follow\nat least\n4 friends!", for: .normal)
self.optionC.isEnabled = false
self.optionD.setTitle("Follow\nat least\n4 friends!", for: .normal)
self.optionD.isEnabled = false
}
else if namesRemaining == 0 {
self.currNames = names
self.optionA.setTitle(names[0], for: .normal)
let optionAUrl = URL.init(string: namesWithUrl[names[0]]!)
self.imageViewA.sd_setImage(with: optionAUrl)
self.optionB.setTitle(names[1], for: .normal)
let optionBUrl = URL.init(string: namesWithUrl[names[1]]!)
self.imageViewB.sd_setImage(with: optionBUrl)
self.optionC.setTitle(names[2], for: .normal)
let optionCUrl = URL.init(string: namesWithUrl[names[2]]!)
self.imageViewC.sd_setImage(with: optionCUrl)
self.optionD.setTitle(names[3], for: .normal)
let optionDUrl = URL.init(string: namesWithUrl[names[3]]!)
self.imageViewD.sd_setImage(with: optionDUrl)
}
//self.dismiss(animated: true, completion: nil) //it works when i don't include this otherwise there is a bug
})
}
//self.dismiss(animated: true, completion: nil) //it works when i don't include this otherwise there is a bug out
})
}
更新:
我从firebase复制了一段我的Realtime DB JSON结构:
"following" : {
"MJxCFUX0jpXJD1a2u0iqt6xSAdB3" : {
"5W6Qf4cJKQb5nY1PthMUelHLShy2" : true,
"GU03rUQPrIX4zleX1S8L8anSWmn2" : true,
"MfeIehKJKzS2Cf0kA0JTmHZGWSu1" : true
},
"MfeIehKJKzS2Cf0kA0JTmHZGWSu1" : {
"5W6Qf4cJKQb5nY1PthMUelHLShy2" : true,
"GU03rUQPrIX4zleX1S8L8anSWmn2" : true,
"MJxCFUX0jpXJD1a2u0iqt6xSAdB3" : true,
"nZLf70wvZUYqrAExXmnSX9G7Rar2" : true
},
"nZLf70wvZUYqrAExXmnSX9G7Rar2" : {
"5W6Qf4cJKQb5nY1PthMUelHLShy2" : true,
"FwUzqbn49FP5jS5mIuaAEnrxvpj2" : true,
"GU03rUQPrIX4zleX1S8L8anSWmn2" : true,
"MJxCFUX0jpXJD1a2u0iqt6xSAdB3" : true,
"MfeIehKJKzS2Cf0kA0JTmHZGWSu1" : true
}
"users" : {
"5W6Qf4cJKQb5nY1PthMUelHLShy2" : {
"email" : "[email protected]",
"fullname" : "Aaaa",
"fullname_lowercase" : "aaaa",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/pinion-4896b.appspot.com/o/profile_image%2F5W6Qf4cJKQb5nY1PthMUelHLShy2?alt=media&token=eba41189-98dc-45d0-bccc-769cc8fa872f"
},
"FwUzqbn49FP5jS5mIuaAEnrxvpj2" : {
"email" : "[email protected]",
"fullname" : "Ffff",
"fullname_lowercase" : "ffff",
"profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/pinion-4896b.appspot.com/o/profile_image%2FFwUzqbn49FP5jS5mIuaAEnrxvpj2?alt=media&token=55649e15-4e6c-4b44-b804-1b4a9e8e4272"
},
}
所以你可以使用observ
函数而不是observeSingleEvent
。来自google doc的例子:postRef.observe(DataEventType.value, with: { (snapshot) in
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
// ...
})
DataEventType(它的枚举)具有下一个值:/// A new child node is added to a location.
FIRDataEventTypeChildAdded,
/// A child node is removed from a location.
FIRDataEventTypeChildRemoved,
/// A child node at a location changes.
FIRDataEventTypeChildChanged,
/// A child node moves relative to the other child nodes at a location.
FIRDataEventTypeChildMoved,
/// Any data changes at a location or, recursively, at any child node.
FIRDataEventTypeValue
Observ
函数就像监听器 - 观察者模式一样工作,因此不要忘记在观察事件时解除订阅。