【问题标题】:Get random child from Firebase Database从 Firebase 数据库中获取随机孩子
【发布时间】:2017-04-07 12:43:54
【问题描述】:

我正在尝试使用 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 的孩子?如果有,怎么做?

【问题讨论】:

  • yes 的问题“是否可以查询数据库,所以我得到 user_uid 等于我提供的用户 uid 的所有孩子?”
  • 我该怎么做? @EICaptainv2.0
  • 你找到答案了吗?
  • 去看看我的帖子here。我想这正是你要找的!如果有帮助,请告诉我。

标签: ios swift xcode firebase firebase-realtime-database


【解决方案1】:

尝试将您的 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 并将其与其他测试详细信息一起放入并设置到您的数据库中
  • 这个过程还在继续......

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

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

【讨论】:

  • 当我开始删除帖子时,这不会有问题吗?那么有些索引会是空的吗?
  • 我已经更新了我的答案。如果它解决了您的问题,请接受并投票作为答案:) 快乐编码
【解决方案2】:
  • 首先,您必须从 firebase 查询所有数据。然后你可以使用普通的随机函数从快照中获取随机值。(第二部分)
  • 要根据用户 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)
     })
    }
    

【讨论】:

  • 所以假设我的数据库中有 100,000 个用户,我应该检索 100,000 个值吗?您确定这是最佳解决方案吗?
  • 这可能不是最佳解决方案,但firebase没有为此提供特定功能。
猜你喜欢
  • 1970-01-01
  • 2017-07-06
  • 2019-01-03
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多