我正在尝试使用Firebase 3和Swift 3来创建一个允许用户创建“测试”的应用程序,目的是让您从数据库中显示一个完全随机的测试。
我的表:
Users:
- uid
- email
tests
- id
- title
- user_uid
如何从“测试”中随机选择任何一个孩子,以便我可以将它们显示给用户?我应该以某种方式改变我的结构吗?
我的意思是说我有这个:
tests:
- 12391239123
- title: "My first test"
- user_uid: 12312345
- 59696995883
- title: "Second test"
- user_uid 12352355
我想选择这两个对象中的一个,因此我可以将它们显示给用户。它必须是完全随机的。
也可以查询数据库,所以我得到所有的孩子,其中user_uid等于我提供的用户uid?如果是这样,怎么样?
答案 0 :(得分:2)
尝试将您的JSON树更改为: -
Users:
- uid
- email
tests
- noOfTotalTest : 4 // Lets say 4
- id
- title
- user_uid
- index // Just index of the post
现在使用此codeBlock: -
FIRDatabase.database().reference().child("tests/noOfTotalTest").observeSingleEvent(of: .value, with: {(Snap) in
let totalNoOfTest = Snap.value as! Int
print(totalNoOfTest)
let randNum = Int(arc4random_uniform(UInt32(totalNoOfTest))) + 1
print(randNum)
FIRDatabase.database().reference().child("tests").queryOrdered(byChild: "index").queryEqual(toValue: randNum).observeSingleEvent(of: .value, with: {(Snapshot) in
print(Snapshot.value!)
})
})
NoW无论何时将测试发布到数据库,您都必须执行以下操作: -
PS: - 为了使帖子只是/ SAVING : -
FIRDatabase.database().reference().child("tests/noOfTotalTest").observeSingleEvent(of: .value, with: {(Snap) in
if Snap.exists(){
// This is not the first post
let totalNoOfTest = Snap.value as! Int
FIRDatabase.database().reference().child("tests").childByAutoId().setValue(["userID" : UID, "details" : Details, "index" : totalNoOfTest + 1])
FIRDatabase.database().reference().child("tests/noOfTotalTest").setValue(totalNoOfTest + 1)
} else {
// This is your first post
FIRDatabase.database().reference().child("tests").childByAutoId().setValue(["userID" : UID, "details" : Details, "index" : 1])
FIRDatabase.database().reference().child("tests/noOfTotalTest").setValue(1)
}
})
要扩展此功能以便您能够删除,您可以保存您需要随机化的节点中活动的索引。
为此,将其添加到您的JSON树: -
active_Indexes :{
12 : true,
09 : true,
198 : true,
11: true,
103 : true,
}
现在你需要的是将这些INDEX存储在字典中,然后随机化数组元素: -
var localIndexDirectory = [Int : Bool]
//Listen to any changes to the database, and update your local index directory accordingly
override func viewDidLoad() {
super.viewDidLoad()
FIRDatabase.database().reference().child("active_Index").observe(.childRemoved, with: {(Snap) in
print(Snap.value)
let keyToBeChanged = Int(Snap.key)!
self.localIndexDirectory.removeValue(forKey: keyToBeChanged)
print(self.localIndexDirectory)
})
FIRDatabase.database().reference().child("active_Index").observe(.childAdded, with: {(Snap) in
print(Snap)
let keyToBeChanged = Int(Snap.key)!
self.localIndexDirectory.updateValue(true, forKey: keyToBeChanged)
print(self.localIndexDirectory)
})
}
这将使您的目录更新为数据库中可用的索引( SINCE .observe 是网络线程中的连续线程),然后您只需要在该特定时间随机化这些索引并查询该特定索引的测试。但是现在要激活应用中的删除功能,您还需要修改 保存 功能,即每当您将新节点保存到数据库时,请确保还附加<数据库中的strong> active_Indexes 节点,具有该特定索引。
PPS: - 您还需要更新安全规则以处理不同的身份验证状态。
答案 1 :(得分:0)
要根据用户ID进行查询,您可以使用以下代码(第1部分)
ref.child("users").queryEqualToValue("userId").observeEventType(.Value, withBlock: { snapshot in
print(snapshot)
}
for _ in 1...10 {
//generate a random number between 1 and the amount of questions you have
var randomNumber = Int(arc4random_uniform(amountOfQuestions - 1)) + 1
//The reference to your questions in firebase (this is an example from firebase itself)
let ref = Firebase(url: "https://dinosaur-facts.firebaseio.com/dinosaurs")
//Order the questions on their value and get the one that has the random value
ref.queryOrderedByChild("value").queryEqualToValue(randomNumber).observeEventType(.ChildAdded, withBlock: { snapshot in
//Do something with the question
println(snapshot.key)
})
}