Way/s to determine table does not exist in firebase [duplicate] - ios

This question already has answers here:
How do I check if a firebase database value exists?
(6 answers)
Closed 4 years ago.
I need to get all the data from a specific table but their are times that the table does not exist in firebase. And I want to know if the reason is the table doesn't exist.
I'm using observe(.childAdded) btw.

Try this if this will work
let ref = Database.database().reference()
ref.observeSingleEvent(of: .value) { (snapshot) in
if snapshot.hasChild("mytable") {
// exist
} else {
// does not exist
}
}

While Elbert's answer works, it downloads more data than needed. It downloads your entire database, to check if one node exists.
I recommend instead to only read the node that you're checking:
let ref = Database.database().reference()
ref.child("mytable").observeSingleEvent(of: .value) { (snapshot) in
if snapshot.exists() {
// exists
} else {
// does not exist
}
}
Also see:
Swift Firebase Check if Value Exists
How do I check if a firebase database value exists?

Related

Firebase retrieving child nested data

I want to retrieve data on with this value 7hmpcTuCAYQAYRqP7RNmnegSd9r2
But i'm getting all four objects in snapshot. I want to get parent key values which contain this key
7hmpcTuCAYQAYRqP7RNmnegSd9r2
Need to get blue mark keys.
Here is my code
let ref = FirebaseManager.refs.databaseRoot.child("new_ChatListMembers")
ref.queryOrdered(byChild: (Auth.auth().currentUser?.uid)!).queryEqual(toValue: true)
ref.observeSingleEvent(of: .value) { (snapshot) in
print(snapshot)
}
This code return four objects instead of two.Please help me how i can get specific data.
Thanks
You're not actually using the query that you construct in your code. To use that, it'd be something like:
let ref = FirebaseManager.refs.databaseRoot.child("new_ChatListMembers")
let query = ref.queryOrdered(byChild: (Auth.auth().currentUser?.uid)!).queryEqual(toValue: true)
query.observeSingleEvent(of: .value) { (snapshot) in
print(snapshot)
}
But this won't actually scale very well, as you'll need to define an index for each individual UID value in this structure. In short: your current data structure makes it each to find the users for a specific chat room, but it doesn't help finding the chat rooms for a specific user.
To allow the latter, you'll want to add an extra structure in your data:
user_chats: {
"$uid": {
"$chatid": true
}
}
So this is pretty much the inverse of what you have already, which is why this is often called an inverse index.
For more on this, and another example, see my answer here: Firebase query if child of child contains a value

for in loop keeps running firebase database swift [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So I have the following code to retreive data from my firebase database:
ref = Database.database().reference().child("data").child("someData")
ref.observeSingleEvent(of: .value) { (snapshot) in
for child in snapshot.children {
let someSnap = child as! DataSnapshot
self.someArray.append(someSnap.key)
self.collectionView?.reloadData()
}
This code succesfully appends the 4 string elements i have in my database to the array in my viewcontroller class, however it does so over and over again. The array keeps growing with hundreds of strings of the same 4 items over and over. How can I get only the 4 items I want?
It seems that you call the function many times , so make sure to clear it
self.someArray.removeAll()
for child in snapshot.children {
let someSnap = child as! DataSnapshot
self.someArray.append(someSnap.key)
}
self.collectionView?.reloadData()
As from your question, you are calling function many times, when you call function again remove all elements from array or clear array and reload your collection view so it does not add same items again. As updated your code:
ref = Database.database().reference().child("data").child("someData")
ref.observeSingleEvent(of: .value) { (snapshot) in
self.someArray.removeAll()
for child in snapshot.children {
let someSnap = child as! DataSnapshot
self.someArray.append(someSnap.key)
}
self.collectionView?.reloadData()
}
Since I don't have access to the database I'd suggest you use the debugger over the for loop and trace it step by step and checking for the values in each iteration to see what exactly you're appending to the array

Value of String won't change in Swift despite clear declaration [duplicate]

This question already has answers here:
Return Statement Error using Firebase in Swift
(1 answer)
Code Not Completing Before Next Method Is Called
(1 answer)
Swift accessing response from function
(1 answer)
Closed 4 years ago.
I am making an app in which I have to return a String representing the existence of a certain reference to my firebase realtime database (I am not using a Bool for other reasons). Despite executing the print commands directly above and below, when I print the function, the value of the String won't change and prints its default value "Unchanged".
My code:
func checkIfMovieHasAlreadyBeenShown(movieID: String) -> String {
var hasItBeenSeen = "Unchanged"
let uid = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("Seen Movies").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.hasChild(movieID){
print("The Result:")
self.changeStringHasItBeenSeen(YNString: "yes")
print("YES")
}
else {
print("The Result:")
self.changeStringHasItBeenSeen(YNString: "no")
print("NO")
}
})
return hasItBeenSeen
}
It is printed here:
print(checkIfMovieHasAlreadyBeenShown(movieID: "39"))
print(checkIfMovieHasAlreadyBeenShown(movieID: "38"))
observeSingleEvent is called in a closure. The return hasItBeenSeen line will not be affected by anything in the closure, as it will return first.
Imagine this: you tell your friend to go buy some apples. Before he has even left, you ask him for the price. Of course, he won't know, because he hasn't gone to buy the apples yet.
You need some way of performing something AFTER the closure has been called (or after the apples have been bought). Usually this can be done with a completion handler, where you pass a closure into your checkIfMovieHasAlreadyBeenShown function, such as, "do this AFTER you buy the apples".
Then you would call your function this way: checkIfMovieHasAlreadyBeenShown(movieID: "39", completion: { seen in print(seen) })

using swift 3 how to retrive data inside another data from firebase [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm trying to fetch data in a specific data such in age_range inside the 'min' which equal to 21
although 'total' inside 'summary' that is inside friends.
i only success fetching normal data such as name and gender ....
your help would be much appreciable
If I understand your question correctly you want to retrieve data from the child of a child.
ref?.child("users").child(uid).child("youCanAddAsManyOfTheseAsYouWishToAccessChildrenOfChildren").observeSingleEvent(of: .value, with: { (snapshot) in
//you can either access children in the line above or by:
snapshot.childSnapshot(forPath: "childName").value
})
If this is not the answer to your question just comment below.
edit: Here is an exact example for you.
ref?.child("users").child(uid).child("FB result").child("age_range").child("min").observeSingleEvent(of: .value, with: { (snapshot) in
//you can either access children in the line above or by:
print(snapshot.value)
})
Swift 3 & Xcode 8.3.2
I hope this code will solve your problem
// Create constant of baseURL (Make your life easier)
let baseURl = Database.database().reference()
// create reference that u want to fetch
let refToFetch = baseURl.child("users").child("uid").child("FB result").child("age_range")
// fetch the value
refToFetch.observeSingleEvent(of: .value, with: { (snapshot) in
// do something with value for key "min"
print(snapshot.value(forKey: "min") ?? "no value")
if let value: Int = snapshot.value(forKey: "min") as? Int {
// You got the value
print("value of min is: \(value)")
}
}) { (error) in
print(error, "Failed to fetch value")
}

How to use Nil in control flow with Firebase snapshots? (Swift) [duplicate]

This question already has answers here:
Checking if Firebase snapshot is equal to nil in Swift
(2 answers)
Closed 6 years ago.
I am trying to check to see if a key/value (TestKey/TestValue) exists at a node and if it does do A and if it does not do B.
I have found this similar thread regarding this on StackOverflow but none of the solutions seemed to work for me: Checking if Firebase snapshot is equal to nil in Swift
I have a database set up that already has the TestKey/TestValue key pair inserted.
Here is my code:
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
//A print test to see stored value before control flow
print(snapshot.value!["TestKey"]) //returns TestValue
print(snapshot.value!["NilKey"]) //returns nil
// I change the value from TestKey <-> NilKey here to test the control flow
if snapshot.value!["TestKey"] != nil {
print("Exists currently")
} else {
print("Does not exist currently")
}
}) { (error) in
print(error.localizedDescription)
}
The problem is that only "A" is executed, even if the print test shows that the result is nil.
I have tried to reverse the operations with == nil and also have tried "is NSNull".
I cannot seem to get the control flow to work properly. Maybe one of the following is the culprit but I am unsure:
interaction of persistence with observesSingleEventOfType
not removing the observer (do I even need to for observeSingleEventType?)
something to do with optionals
something to do with asynchronous calls
something to do with the fact that firebase stores NSAnyObjects
Ultimately the goal is to check if a key/value pair exists and if it does exist: do nothing but if it does not exist: create it.
What am I doing wrong and how can I get this control flow to work?
Ok so after much fiddling I found a solution that works, it was indeed posted as this answer (https://stackoverflow.com/a/35682760/6515861) from the earlier existing question I linked (Checking if Firebase snapshot is equal to nil in Swift).
The way to make it work is to input the TestKey in the reference itself, remove the reference from snapshot.value("TestKey"), and then use "is Null".
Here is the working code:
// Database already exists with "TestKey"/"TestValue"
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
// replace "TestKey" with another string to test for nil
ref.child("TestKey").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if snapshot.value is NSNull {
print("Does not exist currently")
} else {
print("Exists currently")
}
}) { (error) in
print(error.localizedDescription)
}
I am happy I found this solution but if anyone wants to still answer the original question I would love to know why it does not work the other ways.

Resources