Get random child from Firebase Database

后端 未结 2 1849
长发绾君心
长发绾君心 2020-12-04 03:58

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 t

2条回答
  •  失恋的感觉
    2020-12-04 04:35

    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.

提交回复
热议问题