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
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:-
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.
To query based on user id you can use the following code (1st part)
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)
})
}