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

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

问题描述

我试图使用Firebase 3和Swift 3来创建一个允许用户创建测试的应用程序,目的是让您从数据库中看到一个完全随机的测试。



我的表:

 用户:
- uid
- 电子邮件

测试
- id
- title
- user_uid

如何从测试中随机选择任何孩子,以便我可以将其显示给用户?我应该改变我的结构吗?



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

 测试:
- 12391239123
- title:我的第一个测试
- user_uid:12312345
- 59696995883
- title:Second test
- user_uid 12352355

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

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

解决方案

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

 用户:
- uid
- 电子邮件

测试
- noOfTotalTest:4 //让我们说4
- id
- title
- user_uid
- index //只需要索引

现在使用这个codeBlock: - $ /
$ b $ $ $ $ p $ FIRDatabase.database()。 (tests / noOfTotalTest)。observeSingleEvent(:.value,其中:{(Snap)in

$ b let totalNoOfTest = Snap.value as!Int
print(totalNoOfTest )
let randNum = Int(arc4random_uniform(UInt32(totalNoOfTest)))+ 1 $ b $ print(randNum)
FIRDatabase.database()。reference()。child(tests)。queryOrdered (byChild:index)。queryEqual(toValue:randNum).observeSingleEvent(of:.value,with:{(Snapshot)in

print(Snapshot.value!)

})
})

只要您将测试发布到数据库,您都必须执行以下操作:


  • 查询数据库中的测试总数, noOfTotalTest

  • 更新 noOfTotalTest ,并将其与其他测试详细信息放在一起,并将其设置为您的数据库 ..



PS: - 仅用于 : -


$ b

  FIRDatabase.database()。reference()。child(tests / noOfTotalTest)。observeSingleEvent(of:.value ,如下:{(Snap)in 

如果Snap.exists(){

//这不是第一个职位

let totalNoOfTest = Snap.value为! (),userID:UID,details:详细信息,index:totalNoOfTest(); int

FIRDatabase.database() +(1))
FIRDatabase.database()。reference()。child(tests / noOfTotalTest).setValue(totalNoOfTest + 1)
} else {

//这是你的第一个职位

FIRDatabase.database()。reference()。child(tests)。childByAutoId()。setValue(userID:UIDdetails:Details, (1))
FIRDatabase.database()。reference()。child(tests / noOfTotalTest)。setValue(1)



})

为了扩展这个功能,您可以保存活动的索引在你的节点里,你需要随机化。



为了把这个添加到你的JSON树中: - $ /

$ $ $ active_Indexes:{

12:true,
09:true,
198:true,
11:true,
103:true,
}
$ b $现在你需要将这些INDEX存储在一个字典中,然后随机化数组元素:

 var localIndexDirectory = [Int:Bool] 

//监听对数据库的任何更改,并相应更新您的本地索引目录


覆盖func viewDidLoad(){
super.viewDidLoad()

$ b FIRDatabase.database()。reference()。child(active_Index)。observe (.childRemoved,其中:{(Snap)in

print(Snap.value)
let keyToBeChanged = Int(Snap.key)!
self.localIndexDirectory.removeValue(forKey:keyToBeChanged)
print(self.localIndexDirectory)
$ b $)

FIRDatabase.database()。reference ).child(active_Index)。observe(.childAdded,with:{(Snap)in
$ b $ print(Snap)
let keyToBeChanged = Int(Snap.key)!
self.localIndexDirectory.updateValue(true,forKey:keyToBeChanged)
print(self.localIndexDirectory)

))
}

这将使您的目录更新为可用索引( SINCE .observe 是网络线程中的连续线程),那么您所需要的只是在特定时间对这些索引进行随机排序,然后查询该特定索引的 test 。但现在要激活应用程序中的删除功能,您还需要修改 保存 功能,即每当将新节点保存到数据库时,请确保还附加了<



PPS: - 您可以使用您的数据库中的 active_Indexes 还需要更新处理不同身份验证状态的安全规则。


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.

My table:

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.

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?

解决方案

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:-

  • Query for the total no of tests in the DB, noOfTotalTest
  • Once retrieved increment it by +1 and update noOfTotalTest and put it in with other of the test details and set it to your DB
  • And the process carries on....

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.

For that add this to your JSON tree:-

active_Indexes :{

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

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)

    })
}

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:- You would also need to update your security rules for dealing with different authentication states.

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

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