Firebase Swift 3 Xcode 8 - repeat observation results

I looked through the documents on Firebase and through Stack Overflow and YouTube tutorials, but I can learn how to get the data if you get it through Firebase.

I am new to Firebase and in the process of switching my project from Parse to Firebase.

Example: I have data in Firebase that looks like this:

Topics as seen in Firebase

I can capture all topics in Swift by 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 repeat 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 can I get the data:

I need a key (KYCqk2_AVkUd8s9cKiu) I need a description and a name I need an array of tags

- everything in local variables?

Basically, I just want to read in all Topics and have a Topics array in local memory.

I can take care of creating an array of class threads, but I tried several approaches to getting data without any luck. There should be an easy way to analyze the result, but I did not find an example or documentation.

Would thank for help or a pointer to some document or textbook.

===================================

Updated Code

Hi, I changed the code to try to match the pattern. The code now looks lower. I set the loop counter to see what happens and why it crashes.

FDataSnapshot is not defined, so I used FIRDataSnapshot.

Here is a new attempt at code that is now crashing. Next, I show my changes to make this not a failure - and the question of the safe delivery of the tag subtree . 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, but the code stops at that breakpoint (when I know the exact zero breakpoints)

 libswiftCore.dylib`_swift_bridgeNonVerbatimFromObjectiveC: 0x1144a4270 <+0>: pushq %rbp 0x1144a4271 <+1>: movq %rsp, %rbp 0x1144a4274 <+4>: pushq %r15 

... is torn here three times, and then the application crashes in this line let dict = snap.value like! [String: String] with the message "Subject 1: EXC_BAD_INSTRUCTION (code = EXEC_1386_INVOP, lowering = 0x0)

I am not sure why the code has a breakpoint and why it crashes. Maybe crashed when hit tags because tags are sub node and not suitable [String, String]

I print it in a magazine 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 string 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 understood the topic key from the doc link sent by another answer. Thanks.

I'm not sure if I get the tag values ​​correctly. This is actually just a dictionary, and I tried to use it that way, but it crashes at runtime and wants to use tags for NSArray .... so I did it in the code and it works, but not sure if it is safe, since it is not defined as an array, although it is returned as an array.

+8
ios swift firebase firebase-database
source share
3 answers

All about dictionaries really.

Given an example node

 people_foods -Yinasdjasjd name: "Leroy" food: "Pizza" -Yk9j9s9soks name: "Pete" food: "Wings" 

This code receives data as a snapshot and iterates over it to print a person and his food.

  let ref = self.myRootRef.child(byAppendingPath: "people_foods")! ref.observe(.value, with: { snapshot in if ( snapshot!.value is NSNull ) { print("not found") } else { for child in (snapshot?.children)! { let snap = child as! FDataSnapshot //each child is a snapshot let dict = snap.value as! [String: String] // the value is a dict let name = dict["name"] let food = dict["food"] print("\(name) loves \(food)") } } }) 

The parent name of the node of each child can also be found using child.key.

A typical design pattern is to use an array of classes (or dicts or structs, etc.) as a data source for a tableView. You will iterate over the children and create a class for each of them and add it to the tableView. Upon completion, tableView.reloadData will update the user interface.

It is also important to remember that Firebase is asynchronous, so do not try to access or work with this array outside of Observe closure until the code in it completes.

+5
source share

The FIRDataSnapshot value property returns the contents of the snapshot as a standard Foundation type.

+1
source share

You can do this easily with SnapshotParser .

For a quick introduction you will need the following code:

 func main(){ let topics=SnapshotParser().parseAsList(snap: Snapshot, type: Topic.self) for topic in topics{ //do something with your object } } class Topic: ParsableSnapshot { var id:String?=nil var createdBy:String?=nil var description:String?=nil var name:String?=nil var tags:[Int:String]?=nil required init(){} func bindProperties(binder: SnapshotParser.Binder) { binder.bindField(name: "id", field: &id) binder.bindField(name: "createdBy", field: &createdBy) binder.bindField(name: "description", field: &description) binder.bindField(name: "name", field: &name) binder.bindDictionary(name: "tags", dict: &tags) } } 
0
source share

All Articles