How to include firebase snapshot key value? [Swift] - ios

Please anyone who would show me how to include the snapshot key value along with children value that I already append to my array (forgot to include it and now remember I have to) ... aside from that something really I couldn't understand when I tried to solve my own issue, by testing the value first by using this method: print(rooms.popFirst().key!) half of my database values got nil value ?!! and if I don't include that method everything works fine anyways if you can't imagine that nonetheless I really wish your suggestion or advice for getting all data with their own key value...
This is my code so far:
Database.database().reference().child("rooms").observe(.value, with: { (snapshot) in
print()
var rooms = snapshot.value as! [String:AnyObject]
for(_,value) in rooms {
if (rooms.popFirst()?.key) != nil{
let title = value["title"] as? String
let description = value["description"] as? String
let roomPictureUrl = value["Room Picture"] as? String
let longitude = value["Longtitude"] as? String
let latitude = value["Latitude"] as? String
let dateFrom = value["Date From"] as? String
let dateTo = value["Date To"] as? String
let owner = value["Owner"] as? String
let myRooms = Room(roomID: "XXX",title: title!, description: description!, roomPicutreURL: roomPictureUrl!, longitude: longitude!, latitude: latitude!, dateFrom: dateFrom!, dateTo: dateTo!, owner: owner!)
//print(rooms.popFirst()?.key)
self.rooms.append(myRooms)
self.tableView.reloadData()
}
}
})

Try this:
Database.database().reference().child("rooms").observe(.value, with: { (snapshot) in
var rooms = snapshot.value as! [String:AnyObject]
let roomKeys = Array(rooms.keys)
for roomKey in roomKeys {
guard
let value = rooms[roomKey] as? [String:AnyObject]
else
{
continue
}
let title = value["title"] as? String
let description = value["description"] as? String
let roomPictureUrl = value["Room Picture"] as? String
let longitude = value["Longtitude"] as? String
let latitude = value["Latitude"] as? String
let dateFrom = value["Date From"] as? String
let dateTo = value["Date To"] as? String
let owner = value["Owner"] as? String
let myRooms = Room(roomID: "XXX",title: title!, description: description!, roomPicutreURL: roomPictureUrl!, longitude: longitude!, latitude: latitude!, dateFrom: dateFrom!, dateTo: dateTo!, owner: owner!)
print(roomKey)
self.rooms.append(myRooms)
self.tableView.reloadData()
}
}
})

To get the key from snapshot you can use following lines of code it will give you result like -> Kqwewsds12 -> your child Details
let dictValues = [String](snapshot.keys)
print(dictValues[0]) //Output -- Kqwewsds12

Related

getting array of child values from firebase database

database structure
I am trying to get an array of users(strings) from a comment, but am having trouble since it is kinda deep in my database, here is the implementation I've tried, it is returning 0 for the count.
REF_FEEDMESSAGES.child(messageKey).child("comments").observeSingleEvent(of: .value) { (commentSnapshot) in
guard let commentSnapshot = commentSnapshot.children.allObjects as? [DataSnapshot] else {return}
for comment in commentSnapshot {
let theComment = comment.value as? [String: Any]
let theContent = theComment?["content"] as? String ?? ""
let theIcon = theComment?["icon"] as? String ?? ""
let theColor = theComment?["color"] as? String ?? ""
let theDate = theComment?["date"] as? String ?? "0"
let theName = theComment?["userName"] as? String ?? ""
let theVerified = theComment?["isVerified"] as? String ?? "no"
let profileImageURL = theComment?["profileImageURL"] as? String ?? ""
let postedBy = theComment?["postedBy"] as? String ?? ""
let likes = theComment?["likes"] as? String ?? ""
let key = comment.key
let likers = comment.childSnapshot(forPath: "likedBy").value as? [String] ?? []
print(likers.count)
guard let likers = comment.childSnapshot(forPath: "likedBy").children.allObjects as? [DataSnapshot] else {return}
for like in likers {
let theLike = like.value as? [String:Any]
print(theLike!["user"] as? String ?? "")
commentLiked.append(theLike!["user"] as? String ?? "")
}

manually entered data in firebase issue

I am manually entering in data into my database and the only variable not getting passed from my database is the author and I do not know where I am going wrong.
func getAllArticles(handler: #escaping (_ articles: [Article])-> ()){
var articleArray = [Article]()
REF_ARTICLES.observeSingleEvent(of: .value) { (articleMessageSnapshot) in
guard let articleMessageSnapshot = articleMessageSnapshot.children.allObjects as? [DataSnapshot] else {return}
for article in articleMessageSnapshot {
let content = article.childSnapshot(forPath: "content").value as? String ?? "no content"
let author = article.childSnapshot(forPath: "author").value as? String ?? "no author"
let twitterHandle = article.childSnapshot(forPath: "twitterHandle").value as? String ?? "none"
let articleTitle = article.childSnapshot(forPath: "articleTitle").value as? String ?? "no title"
let date = article.childSnapshot(forPath: "date").value as? String ?? "no date"
let article = Article(content: content, author: author, twitterHandle: twitterHandle, ArticleTitle: articleTitle, date: date)
articleArray.append(article)
}
handler(articleArray)
}
}
Please check out below code
var articleArray = [Article]()
//REF_ARTICLES
let ref = Database.database().reference().child(“articles”)
ref.observe(.childAdded, with: { (snapshot) in
print(snapshot)
guard let dictionary = snapshot.value as? [String : AnyObject] else {
return
}
let articleObj = Article()
articleObj.Content = dictionary["content"] as? String
articleObj.Author = dictionary["author"] as? String
articleObj.Twitterhandle = dictionary["twitterHandle"] as? String
articleObj.Title = dictionary["articleTitle"] as? String
articleObj.Date = dictionary["date"] as? String
self. articleArray.append(articleObj)
}, withCancel: nil)
}
I am also working on similar app where i am storing data to firebase and retrieving. Below approach i used to fetch the data from firebase database. Please try once.
func getAllArticles(handler: #escaping (_ articles: [Article])-> ()) {
Database.database().reference().child("Articles").observe(.childAdded, with: { (snapshot) in
print("articles = \(snapshot)")
if let dict = snapshot.value as? [String: Any] {
let article = Article()
article.articleTitle = dict["articleTitle"] as? String
article.author = dict["author"] as? String
article.twitterHandle = dict["twitterHandle"] as? String
article.date = dict["date"] as? String
article.content = dict["content"] as? String
self.articleArray.append(article)
}
handler(articleArray)
}, withCancel: nil)
}
im not sure what the underlying issue was, but i fixed it by deleting "author" from the firebase tree and then adding it back

Return from initializer without initializing all stored properties Xcode 8

I upgraded to Xcode 8 and my app stopped working and I have been able to fix everything but this one error. I have been looking online and I have not found a fix for this error. Any Help would be appreciated.
Here is the code:
struct Party {
let itemRef:FIRDatabaseReference?
//
let userID:String!
let name:String!
let title:String!
let body:String!
init (userID:String, name:String, title:String = "", body:String) {
self.userID = userID
self.name = name
self.title = title
self.body = body
self.itemRef = nil
}
init (snapshot:FIRDataSnapshot) {
userID = snapshot.key
itemRef = snapshot.ref
if let titl = snapshot.value as? [String:AnyObject] {
for child in titl{
let shotKey = snapshot.children.nextObject() as! FIRDataSnapshot
if let title = child.value as? [String:AnyObject]{
let title = title["title"]
print(title)
}
}
}else{
title = "Failed To Display Title"
}
if let user = snapshot.value as? [String:AnyObject] {
for child in user{
let shotKey = snapshot.children.nextObject() as! FIRDataSnapshot
if let name = child.value as? [String:AnyObject]{
let name = name["name"]
print(name)
}
}
}else{
name = "Failed To Display Name"
}
if let partyBody = snapshot.value as? [String:AnyObject]{
for child in partyBody{
let shotKey = snapshot.children.nextObject() as! FIRDataSnapshot
if let body = child.value as? [String:AnyObject]{
let body = body["body"]
print (body)
}
}
}else{
body = "Failed To Display Time"
}
}
func toAnyObject() -> Any {
return ["title":title, "name":name, "body":body]
}
}
Your second init(snapshot:) function doesn't set the name, title, and body properties under certain conditions.
You have this code for the title:
if let titl = snapshot.value as? [String:AnyObject] {
for child in titl{
let shotKey = snapshot.children.nextObject() as! FIRDataSnapshot
if let title = child.value as? [String:AnyObject]{
let title = title["title"]
print(title)
}
}
}else{
title = "Failed To Display Title"
}
This code only sets the title property in the else clause. The four references to title inside the if part are references to local variables named title, not the property named title. So the compiler complains you never set the title property because there is a possible code path where it isn't set.
You have the same issue for name and body.

Add annotation after retrieving users latitude and longitude from Firebase

I am trying to add a mapView annotation of all the online user after retrieving their latitude and longitude from Firebase. I am able to print it as an optional or as a CLLocationDegrees aka Double, but when I try to add it into my user.userAnnotation attribute I get a fatal error. This is what I am printing:
this is the users lat Optional(19.435477800000001)
this is the user latitude in CLLocationDegrees 19.4354778
fatal error: unexpectedly found nil while unwrapping an Optional value
And this is my function:
func fetchOnlineUsers() {
ref = FIRDatabase.database().reference()
FIRDatabase.database().reference().child("users").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = AppUser()
user.userEmail = (snapshot.value as? NSDictionary)?["name"] as? String
user.latitude = (snapshot.value as? NSDictionary)?["latitude"] as? Double
user.longitude = (snapshot.value as? NSDictionary)?["longitude"] as? Double
user.online = ((snapshot.value as? NSDictionary)?["online"] as? Bool)!
print("this is the user latitude \(user.latitude)")
let userLat = CLLocationDegrees(user.latitude!)
let userLon = CLLocationDegrees(user.longitude!)
if user.online == true {
user.userAnnotation.coordinate = CLLocationCoordinate2D(latitude: userLat, longitude: userLon)
self.users.append(user)
}
print("this are the users \(self.users)")
print("this is the dictionary \(dictionary)")
self.mainMapView.addAnnotations([user.userAnnotation])
}
}, withCancel: nil)
}
Well some of the value/s that you´re getting is nil. Try this instead:
guard let dictionary = snapshot.value as? [String: AnyObject],
let email = (snapshot.value as? NSDictionary)?["name"] as? String,
let latitude = (snapshot.value as? NSDictionary)?["latitude"] as? Double,
let longitude = (snapshot.value as? NSDictionary)?["longitude"] as? Double,
let online = ((snapshot.value as? NSDictionary)?["online"] as? Bool)! else { // Some error }
If this succeeds you can start use the variables created in the guard let and they will 1: have a value, 2: not be Optional.

Firebase Query Error in Swift3: Type 'NSFastEnumerationIterator.Element' (aka 'Any') does not conform to protocol 'AnyObject'

I'm not sure how to fix this error. Can someone explain it?
Type 'NSFastEnumerationIterator.Element' (aka 'Any') does not conform to protocol 'AnyObject'
Here's my Query.
media24HourQuery.observe(FIRDataEventType.value, with: { snapshot in
var newItems = [[String: AnyObject]]()
for child in snapshot.children {
let title = (child as AnyObject).value["title"] as? String
let userID = (child as AnyObject).value["userID"] as? String
let mediaID = (child as AnyObject).value["mediaID"] as? String
let timestamp = (child as AnyObject).value["timestamp"] as? Double
edit: this doesn't work either (everything is nil)
for _ in snapshot.children {
let title = (snapshot.value as? NSDictionary)?["title"] as? String
let userID = (snapshot.value as? NSDictionary)?["userID"] as? String
let mediaID = (snapshot.value as? NSDictionary)?["mediaID"] as? String
let timestamp = (snapshot.value as? NSDictionary)?["timestamp"] as? Double
and if I do print (child), this is what I get:
// print(child)
Snap (XsUwNDQB3qPdjYFCOLzANmsjjpf1-1474144681) {
mediaID = "XsUwNDQB3qPdjYFCOLzANmsjjpf1-1474144681";
timestamp = 1474144681490;
title = "outside sep 17";
userID = XsUwNDQB3qPdjYFCOLzANmsjjpf1;
}
edit: solved it. this works:
let snapDic = snapshot.value as? NSDictionary
for child in snapDic! {
print (child)
let childDic = child.value as? NSDictionary
let title = childDic?["title"] as? String
let userID = childDic?["userID"] as? String
let mediaID = childDic?["mediaID"] as? String
let timestamp = childDic?["timestamp"] as? Double

Resources