从Firebase数据库中获取随机孩子

我正在尝试使用Firebase 3和Swift 3来制作一个允许用户创build“testing”的应用程序,目的是从数据库中看到一个完全随机的testing。

我的桌子:

Users: - uid - email tests - id - title - user_uid 

我如何从“testing”中随机select任何孩子,这样我就可以将它们展示给用户? 我应该改变我的结构吗?

通过这个我的意思是让我说我​​有这个:

 tests: - 12391239123 - title: "My first test" - user_uid: 12312345 - 59696995883 - title: "Second test" - user_uid 12352355 

我想select这两个对象中的一个,所以我可以将它们显示给用户。 它必须是完全随机的。

也有可能查询数据库,所以我得到所有的孩子,其中user_uid等于我提供的用户uid? 如果是这样,怎么样?

尝试改变你的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每当你发布一个testing到你的数据库你必须做这些事情:

  • 查询数据库中的testing总数noOfTotalTest
  • 一旦检索到+1,并更新noOfTotalTest并将其与其他testing细节放在一起 ,并将其设置到您的数据库
  • 这个过程继续进行着….

PS: –为了使这个职位/ 节省 : –

  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是networking线程中的连续线程 ),那么您只需在特定时间将这些索引随机化,然后查询该特定索引的testing 。 但现在要激活应用程序中的删除function,您还需要修改保存function,即每当将新节点保存到数据库时,请确保您还将DB中的active_Indexes节点附加到该特定索引。

PPS: –您还需要更新处理不同身份validation状态的安全规则。

  • 首先,你必须查询来自firebase的所有数据。 然后你可以使用正态随机函数从快照中获得一个随机值(第二部分)
  • 要根据用户ID进行查询,您可以使用以下代码(第一部分)

     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) }) }