Swift Retrieve Firebase Data from Database - ios

I'm trying to retrieve data from Firebase but I'm having issues.
let refEmployees = Database.database().reference(withPath: "Employees")
refEmployees.child("Logan").observeSingleEvent(of: .value, with: {
snapshot in
let shift = snapshot.value as? String
self.shifts.append(shift!)
self.workSchedule.reloadData()
})
That is my code, my database looks like this.
When I run it, I get
fatal error: unexpectedly found nil while unwrapping an Optional value
Any ideas? I'm stumped. I also can add information to the database at the same time and change to childAdded and the information loads properly.

Usually I never try to get the reference "withPath", but by child.
I would Try to do it like this:
let ref = Database.database().reference().child("Employees").child("Logan")
On the other part, is a bad practice to force unwrap optionals that you don't know you are actually going to get, I would change the closure to:
ref.observeSingleEvent(of: .value, with: {
snapshot in
guard let shift = snapshot.value as? String else {
print("Value is Nil or not String")
return
}
self.shifts.append(shift)
self.workSchedule.reloadData()
})
Like someone in the comments said, may be a good idea to print the optional value first to see if you are actually getting the value that you need from the database.
Hope this helps

let refEmployees = Data`base.database().reference()
refEmployees,child("Employees").child("Logan").observeSingleEvent(of: .value, with: {
snapshot in
let shift = snapshot.value! as! [String : AnyObject]
let dictKeys = [String](snapshot.keys)
//Will give you all` keys from DB 0,1,2,3,4,5,6
let dictValues = [AnyObject](snapshot.values)
//will give you` all values "off", "off", "2-10"..."off"
//use keys or values append in array if you want as I could not understand what you are trying to save in self.shifts
self.shifts.append(shift!)
self.workSchedule.reloadData()
})

Related

Retrieving data from firebase Realtime Datbase with SwiftUI Xcode 11

For a few days I have been trying to read my data from firebase without success.
Indeed it is a set of tables also containing tables.
This function is to retrieve the subjects and at the same time the paragraphs
func getSubjects() {
let subjectRef = database.child("subjects")
subjectRef.observe(.childAdded, with: { (snapshot) in
for child in snapshot.children {
print(snapshot)
if let snapshot = child as? DataSnapshot,
let subject = Subject(snapshot.value)
//subjectList.append(subject)
// print("Data : \(subject)")
}
})
}
This is the firebase screen
Console screen
On Android I didn't have this problem, but since I'm new to iOS, I'm having a hard time coping.
Any help will be welcome. Thank you
At the moment, you are observing the database for constant changes and it will only run when a child/value has been added into the place you're currently checking, for this you may only want to retrieve a value once, and every time that view is loaded then it will fetch from the database again. It's a lot more efficient and less costly. You may want something like this:
ref = Database.database().reference()
ref.child("subjects").child("0").child("paragraphs").child("0").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let location = value["location"] as? NSDictionary
let title= value?["title"] as? String ?? ""
let text = value?["text"] as? String ?? ""
let latitude = location?["latitude"] as? String ?? ""
let longitude = location?["longitude "] as? String ?? ""
}) { (error) in
print(error.localizedDescription)
}
You think each child with nodes inside it as an array, or a json object. You can cast them into an NSDictionary and use that cast to access values inside them if they're nested.
If they're not nested and in the same level as the place you're watching in the database ref, like for instance, above we are looking in the subjects > 0 > paragraphs > 0 node within the database. Title is a value inside that node and not a child so we can simply get the value of title from the database through the data snapshot given back.
I recommend reading the Docs, they're very good and easy to understand when working with different OS/languages.

Fetch first key from firebase database with swift 4 using ChildAdded

I'm trying to fetch the first key from my firebase database but for some reason nothing is being printed out. How can I get the first key from my firebase database using .childAdded
let userMessagesRef = Database.database().reference().child("user-message").child(uid).child(userId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
print(first)
This in incredibly easy if you literally are asking how to only ever get the first child of a node. Here's how to only get the first child of a /users node
func getFirstChild() {
let usersRef = self.ref.child("users")
usersRef.observeSingleEvent(of: .childAdded, with: { snapshot in
print(snapshot)
})
}
or
print(snapshot.key)
if you just want the key.
Or, if you want to use a query to do the same thing
func getFirstChildAgain() {
let usersRef = self.ref.child("users")
let query = usersRef.queryOrderedByKey().queryLimited(toFirst: 1)
query.observeSingleEvent(of: .value, with: { snapshot in
print(snapshot)
})
}
The child_added event is typically used when retrieving a list of items from the database. Unlike value which returns the entire contents of the location, child_added is triggered once for each existing child and then again every time a new child is added to the specified path. The event callback is passed a snapshot containing the new child's data. For ordering purposes, it is also passed a second argument containing the key of the previous child.
From: Read and Write Data on iOS
Per your requirements, this is possible in .value and childAdded.
var child_array = [String:String]
let userMessagesRef = Database.database().reference().child("user-message").child(uid).child(userId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
let value = snapshot.value as? String ?? "Empty String"
let key = snapshot.key
child_array[key] = value;
}) { (error) in
print(error.localizedDescription)
}
then:
if let first = child_array.first?.key {
print(first) // First Key
}
Big NOTE: child_added randomly collects this data, you should never use it to sort your data

Getting an optional firebase database value when it shouldn't be optional

I am running the following query to get a value from the snapshot, but the value is returning as optional.
ref.child("PGroups").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let groupName = String(rest.childSnapshotForPath("/GroupName").value)
print(groupName)
})
and am getting the following printed statement: "Optional(Name)" as appoosed to just: "Name"
Simply add an exclamation point to tell the compiler to unwrap the optional:
print(groupName!) should print "Name"
Alternatively you could also change your code to something like this:
ref.child("PGroups").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let snapshotValue = snapshot.value as! [String: Any]
let groupName = snapshotValue["GroupName"] as! String
print(groupName)
})

type 'Any?' has no subscript members (using Firebase)

Every time I run this line of code it doesn't work, anyone who can give me a hand in what I can do too change it? Thanks for any help. :)
Below is the error I keep getting
Type Any? has no subscript members
var ref:FIRDatabaseReference?
var refHandle: UInt!
var postData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
refHandle = ref?.observe(FIRDataEventType.value, with:
{ (snapshot) in
let dataDict = snapshot.value as! [String: AnyObject]
print(dataDict)
})
let username: String = (FIRAuth.auth()?.currentUser?.uid)!
ref?.child("Users").child(username).observeSingleEvent(of: .value, with:
{ (snapshot) in
let username = snapshot.value!["Username"] as! String
self.usernameField.text = username
})
}
Two issues.
1. Optionals
This is Swift's way of making a variable be in one of two states namely, have a value or be nil. A variable can only be in one of these states. You make a variable an optional by adding a question mark in front of it.
2. Any
By declaring a variable to be of type Any, this means you're not explicitly stating its type during declaration. Firebase makes all of its returns be of type Any in order to give us developers the option of fiddling with the data as we so please hence less constraints on our side.
snapshot.value is of type Any but Firebase always returns a JSON tree and JSON trees can be represented as Dictionaries. So what should we do?
Since snapshot.value is an optional, we should check first to see if its nil.
If not nil, convert it to a dictionary then start accessing the respective elements inside it.
The code below does the job for you and I've added comments to explain what's happening.
ref?.child("Users").child(username).observeSingleEvent(of: .value, with:
{ (snapshot) in
// This does two things.
// It first checks to see if snapshot.value is nil. If it is nil, then it goes inside the else statement then prints out the statement and stops execution.
// If it isn't nil though, it converts it into a dictionary that maps a String as its key and the value of type AnyObject then stores this dictionary into the variable firebaseResponse.
// I used [String:Any] because this will handle all types of data types. So your data can be Int, String, Double and even Arrays.
guard let firebaseResponse = snapshot.value as? [String:Any] else
{
print("Snapshot is nil hence no data returned")
return
}
// At this point we just convert the respective element back to its proper data type i.e from AnyObject to say String or Int etc
let userName = firebaseResponse["Username"] as! String
self.usernameField.text = username
})

How to read Firebase child value?

I'm a newbie to coding and Swift.
I'm trying to retrieve the value of house1Colour from my Firebase database in my app. I've tried these methods so far.
let eg = FIRDatabase.database().reference(withPath: "test")
(when I use this I get a THREAD 1 Signal SIGABRT error, I'm not sure why)
and:
var test:String!
FIRDatabase.database().reference().child("house1Colour").observeSingleEvent(of: .value, with: {(snap) in
if let snapDict = snap.value as? Dictionary <String, AnyObject>{
self.test = snapDict["house1Colour"] as! String
print(self.test)
}
})
None of them work.
The value of FIRDatabase.database().reference().child("house1Colour") is just the string since you already specified the key house1Colour.
Therefore you should be able to just:
if let snapString = snap.value as? String {
print(snapString)
}

Resources