I have looked through the docs on Firebase and through Stack Overflow and YouTube tutorials, but I can find out how to get at the data if fetch through Firebase.
I am new to Firebase and an in the process of switching my project from Parse to Firebase.
Example: I have a data in Firebase that looks like this:
I can grab all of the topics in Swift doing this:
let refDB = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
let topicsRef = refDB.child("topics")
// FIRDataSnapshot.
topicsRef.observe(.value, with: { snapshot in
for child in snapshot.children {
print("child ------")
print(child)
// Get the bits HOW DO I PARSE EACH SET
}
})
When I iterate through the for-loop, I print things that look like this:
child ------
Snap (-KYCqk2_AVkUd8s9cKit) {
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description = "Match states with their capitals";
name = "State Caiptals";
tags = {
0 = Geography;
1 = USA;
};
}
child ------
Snap (-KYCqk2_AVkUd8s9cKiu) {
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description = "Name the parts of an Atom";
name = "Parts of an Antom";
tags = {
0 = Physics;
1 = Atom;
2 = Electron;
};
}
My problem is, how do I get at the data:
I need the key (KYCqk2_AVkUd8s9cKiu) I need the description and name I need an array of tags
-- all in local variables?
Basically, I just want to read in all the Topics
and have an array of Topics
in local memory.
I can take care of building the array of Class topic, but I have tried several approaches to getting at the data with no luck. There must be an easy way to parse the result, but I have not found an example or documentation.
Would appreciate some help or pointer to some doc or tutorial.
=================================
Updated Code
Hi I changed code to try to match sample provided. Code now looks like below I put in a loop counter to see what is happening and why crashing.
FDataSnapshot is not defined so I used FIRDataSnapshot.
Here is new attempt at code that now crashes. Further below I show my changes to make it not crash - and a question about handing the tags subnode safely. Thanks for the pointer. I now have something that works.
// HERE is a way to get all the Topics
let refDB = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
let topicsRef = refDB.child("topics")
// FIRDataSnapshot.
topicsRef.observe(.value, with: { snapshot in
if snapshot.value is NSNull {
print("not found")
} else {
var loopCount = 1 // count loops to see how may time trying to loop
for child in snapshot.children {
print(" ")
print(" ")
print("child ------ loop \(loopCount)")
print(child)
let snap = child as! FIRDataSnapshot //each child is a snapshot
let dict = snap.value as! [String: String] // the value is a dictionary
let name = dict["name"]!
let description = dict["description"]!
let createdBy = dict["createdBy"]!
print("the bits ------")
print("name .... \(name)")
print("description .... \(description)")
print("createdBy .... \(createdBy)")
loopCount += 1
}
}
})
I have zero breakpoints defined -- however the code stops on this breakpoint (when i have zero breakpoints defined for sure)
libswiftCore.dylib`_swift_bridgeNonVerbatimFromObjectiveC:
0x1144a4270 <+0>: pushq %rbp
0x1144a4271 <+1>: movq %rsp, %rbp
0x1144a4274 <+4>: pushq %r15
... breaks here three times and then the app crashes on this line let dict = snap.value as! [String: String] with message "Thread 1: EXC_BAD_INSTRUCTION (code=EXEC_1386_INVOP, subside=0x0)
I am not sure why the code has breakpoint and why it crashes. Maybe crashed when hits tags because tags is sub node and does not fit [String, String]
I print this in the log and then go boom!!!
child ------ loop 1
Snap (-KYI2MszjC9pK_4oIvKu) {
createdBy = FeMFeeDat4VZb5tmFO2tKixgQIy1;
description = "Match states with their capitals";
name = "State Caiptals";
tags = {
0 = Geography;
1 = USA;
};
}
=====
If I change the line to use 'Any' .... then it works
let dict = snap.value as! [String: Any]
new working code ....
// HERE is a way to get all the Topics
let refDB = FIRDatabase.database().reference(fromURL: firebaseDB_URL)
let topicsRef = refDB.child("topics")
// FIRDataSnapshot.
topicsRef.observe(.value, with: { snapshot in
if snapshot.value is NSNull {
print("not found")
} else {
var loopCount = 1 // count loops to see how may time trying to loop
for child in snapshot.children {
print(" ")
print(" ")
print("child ------ loop \(loopCount)")
let snap = child as! FIRDataSnapshot //each child is a snapshot
if snap.value != nil {
print("key ... \(snap.key)")
let dict = snap.value as! [String: Any] // the value is a dictionary
let name = dict["name"] as! String
let description = dict["description"] as! String
let createdBy = dict["createdBy"] as! String
let tags = dict["tags"] as! NSArray
/* Thought I could loop tags as! Dictionary but that does not work. Compiles but runtime crashes.
var tagsArray = [String]()
if tags != nil && tags.count > 0 {
for (key, value) in tags {
tagsArray.append(value)
}
} */
// Test to see what we got ...
print("the bits ------")
print("name .... \(name)")
print("description .... \(description)")
print("createdBy .... \(createdBy)")
print("tags ... \(tags) ... count \(tags.count)")
loopCount += 1
} else {
print("bad snap")
}
}
}
})
I figured out the topic key from the doc link sent by other response. Thanks.
I am not sure I am getting the tag values correctly. It is really just a Dictionary and I tried to cast it that way but runtime crashes and wants to cast tags to an NSArray .... so I did that in the code and it works but not sure if that is safe since this is not defined as an array even though it is coming back as an array.