从 Firebase 数据库中获取随机子项 [英] Get random child from Firebase Database

查看:19
本文介绍了从 Firebase 数据库中获取随机子项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Firebase 3 和 Swift 3,制作一个允许用户创建测试"的应用,目的是向您展示来自数据库的完全随机测试.

I am trying to use Firebase 3 and Swift 3, to make an app that allows users to create "tests", and the purpose is you're going to be shown a completely random test from the database.

我的桌子:

Users:
- uid
    - email

tests
   - id
      - title
      - user_uid

如何从测试"中随机选择任何孩子,以便将它们显示给用户?我应该以某种方式改变我的结构吗?

How do I random select any child from "tests", so I can display them to the user? Should I change my structure somehow?

我的意思是说我有这个:

By this I mean lets say I have this:

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

我想选择这两个对象之一,以便向用户显示它们.而且它必须是完全随机的.

I want to select one of these two objects, so I can display them to the user. And it has to be completely random.

还有可能查询数据库,所以我得到了 user_uid 等于我提供的用户 uid 的所有孩子?如果是,怎么办?

Also is it possible to query the database, so I get all childs where user_uid is equal to the user uid I supply? If so, how?

推荐答案

尝试将您的 JSON 树更改为:-

Try changing your JSON tree to this :-

Users:
  - uid
     - email

tests
  - noOfTotalTest : 4 // Lets say 4
  - id
     - title
     - user_uid
     - index   // Just index of the post

现在使用这个代码块:-

Now use this 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 whenever you post a test to your database you gotta do these things:-

  • 查询数据库中的测试总数,noOfTotalTest
  • 检索后将其增加 +1 并更新 noOfTotalTest 并将其与其他测试详细信息一起放入并将其设置到您的数据库
  • 这个过程还在继续......

PS:-为了让帖子只是/保存:-

PS:- For making the post just/ 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)  

        }

})

为了扩展它以便您能够删除,您可以保存您需要随机化的节点中活动的索引.

To extend this for you to be able to delete, you can save the indexes that are active in your node's which you need to randomise.

为此,将其添加到您的 JSON 树中:-

For that add this to your JSON tree:-

active_Indexes :{

   12 : true,
   09 : true,
   198 : true,
   11: true,
   103 : true,
  }

现在您需要的是将这些 INDEX 存储在字典中,然后随机化数组元素:-

Now what you need is to store these INDEX in an dictionary , then randomise the array element :-

 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 节点,具有该特定索引.

This will keep your directory updated for the indexes available(SINCE .observe is a continuos thread in your network thread) in your database, then all you need is to randomise those indexes at that particular time and query that test for that particular index. But now to activate the Deleting function in your app you also need to modify your saving function i.e whenever you save a new node to your database, make sure you also append the active_Indexes node in your DB, with that particular index.

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

PPS:- You would also need to update your security rules for dealing with different authentication states.

这篇关于从 Firebase 数据库中获取随机子项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆