Ios 从Firebase数据库中获取随机子项

Ios 从Firebase数据库中获取随机子项,ios,swift,xcode,firebase,firebase-realtime-database,Ios,Swift,Xcode,Firebase,Firebase Realtime Database,我正在尝试使用Firebase 3和Swift 3,制作一个允许用户创建“测试”的应用程序,目的是向您展示一个来自数据库的完全随机测试 我的桌子: Users: - uid - email tests - id - title - user_uid 如何从“测试”中随机选择任何子项,以便向用户显示它们?我应该改变我的结构吗 我的意思是说我有: tests: - 12391239123 - title: "My first test" -

我正在尝试使用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
我想从这两个对象中选择一个,以便向用户显示它们。它必须是完全随机的

也可以查询数据库,这样我就可以得到所有的child,其中user_uid等于我提供的user uid?如果是,怎么做?

  • 首先,您必须从firebase查询所有数据。然后可以使用普通随机函数从快照中获取随机值。(第二部分)
  • 要根据用户id进行查询,可以使用以下代码(第一部分)

      • 首先,您必须从firebase查询所有数据。然后可以使用普通随机函数从快照中获取随机值。(第二部分)
      • 要根据用户id进行查询,可以使用以下代码(第一部分)


      尝试将JSON树更改为:

      Users:
        - uid
           - email
      
      tests
        - noOfTotalTest : 4 // Lets say 4
        - id
           - title
           - user_uid
           - index   // Just index of the post
      
      现在使用这个代码块:-

          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!)
      
              })
          })
      
      现在,无论何时向数据库发布测试,都必须执行以下操作:-

      • 查询数据库中的测试总数,noOfTotalTest
      • 检索后,将其增量为+1,并更新noOfTotalTest,将其与其他测试详细信息一起放入,并将其设置为您的DB
      • 这个过程还在继续
      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,
        }
      
      现在,您需要将这些索引存储在字典中,然后随机化数组元素:-

       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)
      
          })
      }
      
      这将为数据库中可用的索引(保持目录的更新,因为.observe是网络线程中的continuous线程),那么您所需要的就是在特定时间对这些索引进行随机化,并查询该特定索引的测试。但现在要激活应用程序中的删除功能,您还需要修改保存功能,即每当您将新节点保存到数据库中时,请确保您还将数据库中的活动索引节点附加到该特定索引中


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

      尝试将JSON树更改为:

      Users:
        - uid
           - email
      
      tests
        - noOfTotalTest : 4 // Lets say 4
        - id
           - title
           - user_uid
           - index   // Just index of the post
      
      现在使用这个代码块:-

          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!)
      
              })
          })
      
      现在,无论何时向数据库发布测试,都必须执行以下操作:-

      • 查询数据库中的测试总数,noOfTotalTest
      • 检索后,将其增量为+1,并更新noOfTotalTest,将其与其他测试详细信息一起放入,并将其设置为您的DB
      • 这个过程还在继续
      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,
        }
      
      现在,您需要将这些索引存储在字典中,然后随机化数组元素:-

       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)
      
          })
      }
      
      这将为数据库中可用的索引(保持目录的更新,因为.observe是网络线程中的continuous线程),那么您所需要的就是在特定时间对这些索引进行随机化,并查询该特定索引的测试。但现在要激活应用程序中的删除功能,您还需要修改保存功能,即每当您将新节点保存到数据库中时,请确保您还将数据库中的活动索引节点附加到该特定索引中


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

      对于问题“是否可以查询数据库,这样我就可以得到用户uid等于我提供的用户uid的所有孩子?”是的,我该如何做@eCaptainV2.0找到答案了吗?请查看我的帖子。我想这正是你想要的!如果有帮助,请告诉我。对于问题“是否可以查询数据库,以便我得到所有的孩子,其中user_uid等于我提供的user uid?”是的,我将如何做到这一点@eCaptainV2.0找到答案了吗?请查看我的帖子。我想这正是你想要的!如果有帮助,请告诉我。假设我的数据库中有100000个用户,我应该检索100000个值吗?您确定这是最佳解决方案吗?这可能不是最佳解决方案,但firebase没有为此提供特定功能。因此,假设我的数据库中有100000个用户,我应该检索100000个值?你确定这是一个最佳解决方案吗?这可能不是最佳解决方案,但firebase没有为此提供特定功能。当我开始删除帖子时,这不会成为问题吗?那么一些索引将是空的?我已经更新了我的答案。如果它解决了你的问题,请接受并投票作为答案:)快乐编码当我开始删除帖子时,这不会成为问题吗?那么一些索引将是空的?我已经更新了我的答案。如果它解决了您的问题,请接受并投票作为答案:)快乐编码