firebase swift empty array out of observer - arrays

In my viewController I have an array of class Users named arrayUtenti, with the code below I need to add that user to that array but for some reason that i cannot understand I get an empty array, what could happened?
**************EDITED WORKS**************
func vengodaEditPremuto(completionHandler:#escaping ([Users]) -> ()){ self.root.child("users").child("ZJq98gvOEHaLUqYTbp4xF52f2K23").observeSingleEvent(of: .value, with: { (snapshot) in
var TempArray: [Users] = []
guard
let value = snapshot.value as? [String:AnyObject],
let userid = value["id"],
let username = value["name"],
let useremail = value["email"]
else {return}
let utenteesistente = Users(id: userid as? String, name: username as? String, email: useremail as? String)
TempArray.append(utenteesistente)
self.arrayUtenti = TempArray
completionHandler(self.arrayUtenti)
print(self.arrayUtenti) //here is ok
})
print(self.arrayUtenti) //here the array is empty!!
}

Your code looks fine after my comment. This is the last thing you need to do to make a correct call:
vengodaEditPremuto(){ result in
print(result)
}

Related

How to get firebase data as a array

public func getAllItems(completion: #escaping (Result<[Item], Error>) -> Void)
{
database.child("Items").observe(.value, with: {snapshot in
guard (snapshot.value as? [[String: Any]]) == nil else{
completion(.failure(DatabaseError.failedToFetch))
return
}
var newUrlArray: [Item] = []
var newItemArray: [Item] = []
for child in snapshot.children{
if let childSnapshots = child as? DataSnapshot,
let dict = childSnapshots.value as? [String:Any],
let title = dict["title"] as? String,
let content = dict["content"] as? String,
let itemId = dict["itemid"] as? String,
let price = dict["price"] as? Int{
let item = Item(title: title, content: content, itemId: itemId, price: price, urs: newUrlArray)
newItemArray.append(item)
}
}
completion(.success(newDataArray))
})
}
My question is how can I get urls that shown in picture as an array or is it possible.
You need to go one level deeper into your JSON/Snapshot hierarchy to get the URLs.
If I remove the non-URL code for a moment for readability, it'd be something like:
for child in snapshot.children{
if let childSnapshots = child as? DataSnapshot,
let dict = childSnapshots.value as? [String:Any],
let urls = childSnapshots.childSnapshot(atPath: "urls").value as? [String:Any],
...
}
}
So urls above is another dictionary, where you can loop over its keys to get the URL values.

Swift4, Firebase - Retrieve only value of key and put in array

I want to retrieve all the values of 'itemname' from Firebase and put them in my array generatedObjects. Now it seems like i get the parent, and also the key and value of its children, when i only want all values of 'itemname' ('Toiletry bag', 'Toothbrush' etc.). Not sure where to go from here, appreciate any help:
My code:
self.ref.child("lists").child("-LOXr5PoUvBn_tGNhql-").child(whatList!).observeSingleEvent(of: .value, with: { (snapshot) in
let children = snapshot.children
while let rest = children.nextObject() as? DataSnapshot{
print(rest.value)
//self.generatedObjects.append(rest.value as! [String: AnyObject])
}
},withCancel: nil)
Try this
func getData() {
ref.child("lists").child("-LOXr5PoUvBn_tGNhql-").child("mylist").observe(.childAdded) { (snapshot) in
let result = snapshot.value as? [String: Any]
let item = result!["itemname"]
//append item to your array
...
}
}
func fetchdata(toId: String)
{
Database.database().reference().child("Users").child(toId).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? [String:Any] else {return}
let itemname = dictionary["itemname"] as! String
print(itemname)
}
}
does it helpfull!!

Reading an array in Firebase

I need some help in reading the "users" array in my Firebase structure as shown below.
I use the below function to grab the data from the channels table.
func observeChannels(channelId: String, onSuccess: #escaping (ChannelModel) -> Void) {
DB_REF_CHANNELS.child(channelId).observeSingleEvent(of: .value) { (snapshot) in
if let dict = snapshot.value as? [String: Any] {
let channel = ChannelModel.transformChannel(dict: dict, key: snapshot.key)
onSuccess(channel)
}
}
}
This is then passed to the ChannelModel class so I can grab each individual data.
class ChannelModel {
var channelId: String?
var channelName: String?
var ownerId: String?
var users: Dictionary<String, Any>? // Array of users }
extension ChannelModel {
static func transformChannel(dict: [String: Any], key: String) -> ChannelModel {
let channel = ChannelModel()
channel.channelId = key
channel.channelName = dict["channelName"] as? String
channel.ownerId = dict["ownerId"] as? String
channel.users = dict["users"] as? Dictionary<String, Any>
return channel
}}
The observeChannels function is then called which returns me an object of all the channels.
observeChannels(channelId: channelId, onSuccess: { (channel) in
self.channels.insert(channel, at: 0)
self.tableView.reloadData()
let user = channel.users!
print(user)
})
When I run the above function to get the users, my output is as follows:
["pZaEJ5aAAkR7WzgIJ4Wqf10jXot1": 1, "asdasldljAlsjkasldj": 1]
I was wondering how would I just get the key value - i.e:
["pZaEJ5aAAkR7WzgIJ4Wqf10jXot1", "asdasldljAlsjkasldj"]
Thanks in advance!
Try this:
let usersDictionary = channel.users!
usersArray = Array(usersDictionary.keys)
print(usersArray)
instead of:
let user = channel.users!
print(user)

Retrieve JSON data in swift

I can't retrieve and print the jobDate data. what's wrong my code?
let retrievetime = UserDefaults().value(forKey: "retrieve")as? NSDictionary
print(retrievetime!)
if let job = retrievetime!["jobs"] as? [String:Any], let jobTitle = job["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
//self.navigationItem.title = "Test"
print retrieve time! json output:
{
jobs =({
jobDate = "2017-08-31";
jobEndTime = 1504144800;
jobID = 87;
jobTime = 1504137600;
});
message = "Retrieve Sucessfully";
result = success;
}
First of all use use the standard singleton instance and optional bindings to safely get data from UserDefaults – unless you registered the key/value pairs.
Second of all never use value(forKey with UserDefaults and never use NSDictionary in Swift unless the compiler tells you to do.
Finally as mentioned in the comments the value for key jobs – as the plural form implies – is an array, you have to get the first object of the array
if let retrievetime = UserDefaults.standard.object(forKey: "retrieve") as? [String:Any] {
print(retrievetime)
if let jobs = retrievetime["jobs"] as? [[String:Any]],
let job = jobs.first,
let jobTitle = job["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
}
let retrievetime = UserDefaults().value(forKey: "retrieve")as? NSDictionary
print(retrievetime!)
if let job = retrievetime!["jobs"] as? [String:Any], let jobTitle = ((retrievetime!["jobs"] as? [String:Any])[0] as? NSDictionary)["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
//self.navigationItem.title = "Test"

How to access nested JSON in brackets in Swift?

I have a JSON response which is in brackets and I struggle to access the inner fields e.g. display_name with Swift. How can I do that?
Optional(["result": {
user = {
"display_name" = "Max Test";
email = "test.max#gmail.com";
"fb_id" = 10209982554704497;
roles = (
stu
);
schools = "<null>";
};
}])
The code I used to access the JSON:
self.restApi.getProfileDetails() {responseObject, error in
//parse down the first layer of array
let response = responseObject as? [String:AnyObject]
print("response object when MyDetailsController opened")
print(response)
let result = response!["result"] as? [AnyObject]
print("result object")
print(result)
//parse down the second layer of JSON object
if let result = response!["result"] as? [AnyObject] {
print("result object when MyDetailsController opened")
// work with the content of "result", for example:
if let user = result[0] as? [String:AnyObject]{
print(user)
let displayName = user["display_name"]
print("displayName")
print(displayName)
}
}
It seems that I address the result in the wrong way as it is always nil:
The console output:
result object
nil
In response result is dictionary not array, try to get like this
let result = response!["result"] as? [String:AnyObject]
1-Get the result object from response
2-Get the user object from result object
3-Get the user info as String from user object .
let response = responseObject as? [String: AnyObject]
let result = response!["result"] as? [String: AnyObject]
if let user = result!["user"] as? [String: AnyObject] {
let displayName = user["display_name"] as? String
let email = user["email"] as? String
}

Resources