Can't load my current user's posts from Firebase - Swift - swift

I want to load my current user's posts from my Firebase Database.
This is my database's architecture:
I have already successfully loaded all the posts into a home view but when I tried to duplicate and use the same method here with the necessary changes and using the uid for the current user's posts, it's not showing anything... Have run out of ideas as to what the problem might be, could use some help.
Here's a screenshot from the ProfileUserPosts swift file:
//VARS
var postsuser = [ProfileUserPosts]()
#objc func observeUserPosts() {
let uid = Auth.auth().currentUser?.uid
let postsRef = Database.database().reference().child("posts").child("author")
postsRef.queryOrdered(byChild: "userid").queryEqual(toValue: uid!).observe(.value) { (snapshot) in
var tempPost = [ProfileUserPosts]()
for child in snapshot.children {
if let childSnapshot = child as? DataSnapshot {
let dict = childSnapshot.value as? [String: Any]
//Post Picture
let photoUrl = dict!["photoUrl"] as? String
let url = URL(string: photoUrl!)
//Info Post
let comments = dict!["comments"] as? String
let city = dict!["city"] as? String
let municipality = dict!["municipality"] as? String
let breed = dict!["breed"] as? String
let phoneuser = dict!["phone"] as? String
let postType = dict!["postType"] as? String
let petType = dict!["petType"] as? String
let gender = dict!["gender"] as? String
let timestampadoption = dict!["timestamp"] as? Double
let date = Date(timeIntervalSince1970: timestampadoption!/1000)
let post = ProfileUserPosts(breed: breed!, phone: phoneuser!, photoUrl: url!, city: city!, municipality: municipality!, petType: petType!, gender: gender!, timestamp: date, postType: postType!, comments: comments!)
tempPost.insert(post, at: 0)
}
DispatchQueue.main.async {
self.postsuser = tempPost
self.postsCollectionView.reloadData()
self.refresher.endRefreshing()
}
}
}
}
Here's where I'm loading the CollectionView with the numberOfItemsInSection and cellForItem
extension ProfileViewController: UICollectionViewDataSource,UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return postsuser.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: PostsCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "postsCell", for: indexPath) as! PostsCollectionViewCell
cell.set(post: postsuser[indexPath.row])
return cell
}
}

Well, my guess - based on your database structure - is that you're accessing an invalid path.
When you've referenced Database.database().reference().child("posts").child("author"), you're saying that posts have a direct child to author and that's not true, they've a direct child of a post id, which then fetching the respective post, you can get the author, so in this case, you would've to iterate through all the posts.
So, to fetch all the posts:
let postsRef = Database.database().reference().child("posts")
then you would have an Object (very important - this is not an array) of posts with ID's as keys, then you would iterate through them and fetch the respective author you want. I won't get into details of your implementation, but just to clarify what I'm saying:
let specificPostAuthor = postsRef.child("LOj1UZZgUnKa28xVtht").child("author")
would return the respective post author.

Related

Reloading tableView after liking a button in cell

My tableView shows some user comments loaded via Firebase Database. The tableView contains also a prototype cell. First of all loadPosts() gets executed. It loads every post and also goes to the user and takes the profile picture which is up to date and at last it sorts them after time.
Now the user has the option to like a post. In the extension UITableViewDelegate I created a cell.buttonAction. Here it opens into the users account and looks if he already liked the post with a specific id. If not it adds +1. If it did already it takes one -1.
The code itself works. But I have huge performance issues. Sometime the tableView gets updated immidiately. Sometimes I have to manually refresh it. As you can see right now I use observeSingleEvent. Should I better use observe instead? But then it crashes sometimes if someone posts and I have the same tableView opened. I also don't want it to reload every time the whole tableView if someone liked a post.
I also created a Video. Maybe it helps. I really do not know how I can solve that problem.
func loadPosts() {
let placeIdFromSearch = ViewController.placeidUebertragen
ref = Database.database().reference().child("placeID/\(placeIdFromSearch)")
ref.queryOrdered(byChild: "userTime").queryLimited(toLast: 10).observeSingleEvent(of: DataEventType.value, with: {(snapshot) in
self.table.removeAll()
for video in snapshot.children.allObjects as! [DataSnapshot] {
let Object = video.value as? [String: AnyObject]
let timestampDate = NSDate(timeIntervalSince1970: Double(Object?["userTime"] as! NSNumber)/1000)
...
let time = dateFormatter.string(from: timestampDate as Date)
...
let userTimeForArranging = Object?["userTime"]
ViewComments.commentIDNew = commentId as! String
getProfilePicture()
func getProfilePicture(){
self.ref = Database.database().reference()
self.ref.child("user/\(userID!)").observe (.value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let userImage = value?["picture"] as? String ?? ""
let userName = value?["firstname"] as? String ?? ""
let video = importComment(userName: userName as! String, userGroup: userGroup as! String, userComment: userComment as! String, userTime: userTime as! String, userLikes: userLikes as! Int, commentId: commentId as! String, placeID: placeID as! String, kommentarCount: kommentarCount as! Int, userImage: userImage as! String, userTimeForArranging: userTimeForArranging as! Int)
self.table.insert(video, at: 0)
self.table = self.table.sorted(by: { $0.userTimeForArranging! > $1.userTimeForArranging! })
self.tableView.reloadData()
})
}
}
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
let video: importComment
video = table[indexPath.row]
cell.layoutMargins = UIEdgeInsets.zero
...
cell.userImage.image = UIImage(url: URL(string: video.userImage!))
cell.buttonAction = {
getClickedRow(arg: true, completion: { (success) -> Void in
if success {
self.loadPosts()
} else {
}
})
func getClickedRow(arg: Bool, completion: #escaping (Bool) -> ()) {
let selectedIndexPath = self.table[indexPath.row].commentId!
ViewSubComments.subCommentIdNew = selectedIndexPath
completion(arg)
}
}
return cell
}
From Prototype cell:
#IBAction func buttonTapped(_ sender: UIButton) {
buttonAction?()
let ref = Database.database().reference()
let userID = Auth.auth().currentUser!.uid
ref.child("user/\(userID)/places/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists(){
getLikeAndMinusOne ()
let database = Database.database().reference()
database.child("user/\(userID)/places/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").removeValue()
}else{
getLikeAndAddOne ()
let database = Database.database().reference()
let object: [String: Any] = [
"like": "true",]
database.child("user/\(userID)/places/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").setValue(object)
}
})
func getLikeAndAddOne () {
let database = Database.database().reference()
database.child("placeID/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").observeSingleEvent(of: .value, with: { (snapshot) in
let userDict = snapshot.value as! [String: Any]
let userLikes = userDict["userLikes"] as! Int
var userLikesNeu = Int(userLikes)
userLikesNeu = Int(userLikes) + 1
database.child("placeID/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").updateChildValues(["userLikes": userLikesNeu])
})}
func getLikeAndMinusOne () {
let database = Database.database().reference()
database.child("placeID/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").observeSingleEvent(of: .value, with: { (snapshot) in
let userDict = snapshot.value as! [String: Any]
let userLikes = userDict["userLikes"] as! Int
var userLikesNeu = Int(userLikes)
userLikesNeu = Int(userLikes) - 1
database.child("placeID/\(ViewController.placeidUebertragen)/\(ViewComments.commentIDNew)").updateChildValues(["userLikes": userLikesNeu])
})}
}

Showing post data from logged in user only swift/xcode/firebase

Hey I have been following tutorials online to try and make a social media app and it works fine where all the posts made by users populates in one scene but in another scene I would like for the users who are currently logged in to be able to see their posts only instead of having to find their posts from a bunch of posts made by other users, below are my code samples:
Posts Code:
import Foundation
import UIKit
import Firebase
class Posts{
var id: String
var author: UserProfile
var text: String
var timestamp:Double
var createdAt:Date
init(id:String, author:UserProfile,text:String,timestamp:Double) {
self.id = id
self.author = author
self.text = text
self.timestamp = timestamp
self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
}
static func parse(_ key:String, _ data:[String:Any]) -> Posts? {
if let author = data["author"] as? [String:Any],
let uid = author["uid"] as? String,
let name = author["name"] as? String,
let photoURL = author["photoURL"] as? String,
let url = URL(string:photoURL),
let text = data["text"] as? String,
let timestamp = data["timestamp"] as? Double {
let userProfile = UserProfile(uid: uid, name: name, photoURL: url)
return Posts(id: key, author: userProfile, text: text, timestamp:timestamp)
func performDeepQuery() {
guard let user = Auth.auth().currentUser else { return }
let uid = user.uid
let ref = Database.database().reference().child("posts")
let query = ref.queryOrdered(byChild: "author/uid").queryEqual(toValue: uid)
query.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
let text = postSnap.childSnapshot(forPath: "text").value as? String ?? "No Text"
print(text)
//same as above
}
})
}
}
return nil }
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return theposts.count
case 1:
return fetchingMore ? 1 : 0
default:
return 0
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 { let cell = HomeViewControllerScene.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! Posting_TableViewCell
cell.set(theposts: theposts[indexPath.row])
return cell}
else {
let cell = HomeViewControllerScene.dequeueReusableCell(withIdentifier: "loadingCell", for: indexPath) as! LoadingCell
cell.spinner.startAnimating()
return cell
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeights[indexPath] ?? 72.0
}
Please someone help me out here I have been scratching my head for a while with this!!!
I believe the question is how to get the posts for a certain user. The structure looks good but no need to have a child node 'author' in each post so instead of this:
posts
post_id_0
author
author data
text: "Hello, World"
uid: "uid_0"
do this
posts
post_id_0
text: "Hello, World"
uid: "uid_0"
name: "usmaan"
photoURL:"https://firebasestorage..."
So now just query for this users posts (this is for Firestore, scroll down fo the RTDB solution)...
func getThisUsersPosts() {
let uid = "uid_0" //this users uid
self.db.collection("posts]").whereField("uid", isEqualTo: uid).getDocuments { (snapshot, error) in
if let err = error {
print(err.localizedDescription)
return
}
if let doc = snapshot?.documents {
for d in doc {
let text = d.get("text") as? String ?? "No Post Text"
print(text)
}
} else {
print("no posts found")
}
}
}
self.db points to my Firestore.
EDIT:
OP is using the Real Time Database so here's the code for that
func getThisUsersPosts() {
let uid = "uid_0"
let ref = self.ref.child("posts") //self.ref points to MY firebase.
let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: uid)
query.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
let text = postSnap.childSnapshot(forPath: "text").value as? String ?? "No Text"
print(text)
}
})
}
EDIT 2:
OP wants to keep their same structure.
To query for data that's two levels deep we use what's called Deep Query and will look something like this:
func performDeepQuery() {
let uid = "uid_0"
let ref = self.ref.child("posts")
let query = ref.queryOrdered(byChild: "author/uid").queryEqual(toValue: uid)
query.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
//populate your tableView datasource here
let post = PostClass()
post.postId = postSnap.key
post.name = postStap.childSnapshot("name").value as? String ?? "No Post Name"
post.text = postStap.childSnapshot("text").value as? String ?? "No Post Text"
self.postArray.append(post)
}
self.myTableView.reloadData()
})
}
which will perform a deep query on this structure
posts
post_0
author
uid: "uid_0"
name: "post 0 name"
text: "post 0 text"
The PostClass could be this
class PostClass {
var postId = ""
var name = ""
var text = ""
}
More Info:
To get the current users uid (which is covered in the getting started guide as well) and assuming you are authenticated (otherwise it will be nil)
guard let user = Auth.auth().currentUser else { return }
let uid = user.uid

How to Firebase retrieve data below UID and auto ID In Swift

[enter image description here][1]I'm trying to retrieve specific data from Database. I'd like to read all data in product_list
My Database
This is what i try but when i print listName. It show like this listName = nil
let refList = Database.database().reference().child("Users/Sellers")
refList.observe(DataEventType.value, with:{(snapshot) in
if snapshot.childrenCount>0{
self.listProduct.removeAll()
for lists in snapshot.children.allObjects as! [DataSnapshot]{
let userList = lists.value as? [String: AnyObject]
let listName = userList?["name"]
let listDetail = userList?["detail"]
let listPrice = userList?["price"]
print("key = \(listName)")
let list = ListModel(name: listName as! String?, detail: listDetail as! String?, price: listPrice as! String?)
self.listProduct.append(list)
}
self.tableList.reloadData()
}
})
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewControllerTableViewCell
let list: ListModel
list = listProduct[indexPath.row]
cell.lblName.text = list.name
cell.lblDetail.text = list.detail
cell.lblPrice.text = list.price
return cell
}
It have 4 things i want to retrieve
(details, name, price and product_image_url)
Right now your code is looping over the child nodes of /Users/Sellers, which is the nodes of each individual user. What you seem to want to do is include all nodes under the product_list property of each user, which requires an extra nested loop:
let refList = Database.database().reference().child("Users/Sellers")
refList.observe(DataEventType.value, with:{(snapshot) in
if snapshot.childrenCount>0{
self.listProduct.removeAll()
for user in snapshot.children.allObjects as! [DataSnapshot]{
let productList = user.childSnapshot(forPath: "product_list")
for product in productList.children.allObjects as! [DataSnapshot]{
let userList = product.value as? [String: AnyObject]
let listName = userList?["name"]
let listDetail = userList?["details"] // NOTE: also fixed a typo here
let listPrice = userList?["price"]
print("key = \(listName)")
let list = ListModel(name: listName as! String?, detail: listDetail as! String?, price: listPrice as! String?)
self.listProduct.append(list)
}
}
self.tableList.reloadData()
}
})

How to sort data in Firebase?

I'm now able to sort posts and users by time.
My data structure looks like that:
posts
-postId
imageRatio:
imageUrl:
postText:
postTime:
uId:
users
-UserId
email:
profileImageURL:
radius:
uid:
username:
username_lowercase:
UPDATE
Now, I created a new class with all datas for the user and the posts:
class UserPostModel {
var post: PostModel?
var user: UserModel?
init(post: PostModel, user: UserModel) {
self.post = post
self.user = user
}
}
Declaration of my post array:
var postArray = [UserPostModel]()
Here, Im loading the datas into the new class:
self.observeRadius(completion: { (radius) in
let currentRadius = radius
// Üperprüfe, welche Posts im Umkreis erstellt wurden
let circleQuery = geoRef.query(at: location!, withRadius: Double(currentRadius)!)
circleQuery.observe(.keyEntered, with: { (postIds, location) in
self.observePost(withPostId: postIds, completion: { (posts) in
guard let userUid = posts.uid else { return }
self.observeUser(uid: userUid, completion: { (users) in
let postArray = UserPostModel(post: posts, user: users)
self.postArray.append(postArray)
print(postArray.post!.postText!, postArray.user!.username!)
self.postArray.sort(by: {$0.post!.secondsFrom1970! > $1.post!.secondsFrom1970!})
})
})
Here I'm loading the datas into the table view cells:
extension DiscoveryViewController: UITableViewDataSource {
// wie viele Zellen
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(postArray.count)
return postArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DiscoveryCollectionViewCell", for: indexPath) as! DiscoveryCollectionViewCell
cell.user = postArray[indexPath.row]
cell.post = postArray[indexPath.row]
//cell.delegate = self
return cell
}
}
Thanks in advance for your help!
There's a lot of code in the question and sometimes, simpler is better. So let's take a Post class, load the posts, get the associated user name and store it in an array. Then when complete, sort and print the posts in reverse chronological order.
A class to hold the post data and the user name
class PostClass {
var post = ""
var timestamp: Int! //using an int for simplicity in this answer
var user_name = ""
init(aPost: String, aUserName: String, aTimestamp: Int) {
self.post = aPost
self.user_name = aUserName
self.timestamp = aTimestamp
}
}
Note that if we want to have have both post data and user data we could do this
class PostUserClass {
var post: PostClass()
var user: UserClass()
}
but we're keeping it simple for this answer.
Then an array to store the posts
var postArray = [PostClass]()
and finally the code to load in all of the posts, get the associated user name (or user object in a full example).
let postsRef = self.ref.child("posts")
let usersRef = self.ref.child("users")
postsRef.observeSingleEvent(of: .value, with: { snapshot in
let lastSnapIndex = snapshot.childrenCount
var index = 0
for child in snapshot.children {
let childSnap = child as! DataSnapshot
let uid = childSnap.childSnapshot(forPath: "uid").value as! String
let post = childSnap.childSnapshot(forPath: "post").value as! String
let timestamp = childSnap.childSnapshot(forPath: "timestamp").value as! Int
let thisUserRef = usersRef.child(uid)
thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
index += 1
//for simplicity, I am grabbing only the user name from the user
// data. You could just as easily create a user object and
// populate it with user data and store that in PostClass
// that would tie a user to a post as in the PostUserClass shown above
let userName = userSnap.childSnapshot(forPath: "Name").value as! String
let aPost = PostClass(aPost: post, aUserName: userName, aTimestamp: timestamp)
self.postArray.append(aPost) //or use self.postUserArray to store
// PostUserClass objects in an array.
if index == lastSnapIndex {
self.sortArrayAndDisplay() //or reload your tableView
}
})
}
})
and then the little function to sort and print to console
func sortArrayAndDisplay() {
self.postArray.sort(by: {$0.timestamp > $1.timestamp})
for post in postArray {
print(post.user_name, post.post, post.timestamp)
}
}
Note that Firebase is asynchronous so before sorting/printing we need to know we are done loading in all of the data. This is handled via the lastSnapIndex and index. The index is only incremented once each user is loaded and when all of the posts and users have been loaded we then sort and print as the data is complete.
This example avoids messy callbacks and completion handlers which may be contributing to the issue in the question - this piece of code is suspect and probably should be avoided due to the asynchronous nature of Firebase; the sort function is going to be called well before all of the users are loaded.
UserApi.shared.observeUserToPost(uid: userUid) { (user) in
self.postUser.append(user)
}
self.postUser.sort(by: {$0.postDate! > $1.postDate!})
*please add error checking.

Fetch data from multiple node in Firebase in Swift

I built my app to have news feed like Facebook. My problem is that I don't know how to fetch child images in Post and show it in a collectionView. Please show me how to do it. Appreciate any help.
Here is the db structure:
Posts
d7j3bWMluvZ6VH4tctQ7B63dU4u1:
20181112101928:
avatar: "https://platform-lookaside.fbsbx.com/platform/p..."
content: "Funny image"
images:
-LR4vaEIggkGekc-5ZME:
"https://firebasestorage.googleapis.com/v0/b/hon..."
-LR4vaENC-IsePibQYxY:
"https://firebasestorage.googleapis.com/v0/b/hon..."
name: "Thành Trung"
time: 1541992768776.3628
type: "Funny"
Here is my code:
func getDataFromPostFirebase() {
let getPostData = databaseReference.child("Posts")
getPostData.observe(.childAdded) { (snapshot) in
getPostData.child(snapshot.key).observe(.childAdded, with: { (snapshot1) in
getPostData.child(snapshot.key).child(snapshot1.key).observe(.value, with: { (snapshot2) in
self.arrayImageUrl = [String]()
if let dict = snapshot2.value as? [String : Any] {
guard let avatar = dict["avatar"] as? String else {return}
guard let content = dict["content"] as? String else {return}
guard let name = dict["name"] as? String else {return}
guard let time = dict["time"] as? Double else {return}
guard let type = dict["type"] as? String else {return}
if let images = dict["images"] as? [String : String] {
for image in images.values {
self.arrayImageUrl.append(image)
}
let newPost = Post(avatarString: avatar, contentString: content, nameString: name, timeDouble: time, typeString: type)
self.arrayPost.append(newPost)
DispatchQueue.main.async {
self.feedTableView.reloadData()
}
} else {
let newPost = Post(avatarString: avatar, contentString: content, nameString: name, timeDouble: time, typeString: type)
self.arrayPost.append(newPost)
DispatchQueue.main.async {
self.feedTableView.reloadData()
}
}
}
})
})
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayImageUrl.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! TrangChu_CollectionViewCell
cell.imgContent.layer.cornerRadius = CGFloat(8)
cell.imgContent.clipsToBounds = true
cell.imgContent.layer.borderWidth = 2
cell.imgContent.layer.borderColor = #colorLiteral(red: 0.4756349325, green: 0.4756467342, blue: 0.4756404161, alpha: 1)
let url = URL(string: arrayImageUrl[indexPath.row])
cell.imgContent.sd_setImage(with: url, completed: nil)
return cell
}
Model object
import Foundation
class Post {
var avatar : String
var content : String
var images : [String]?
var name : String
var time : Double
var type : String
init(avatarString : String, contentString : String, nameString : String, timeDouble : Double, typeString : String) {
avatar = avatarString
content = contentString
// images = imagesString
name = nameString
time = timeDouble
type = typeString
}
}
As what I've said your db is not well structured. I suggest you re structure it like this.
Posts
d7j3bWMluvZ6VH4tctQ7B63dU4u1:
avatar: "https://platform-lookaside.fbsbx.com/platform/p..."
content: "Funny image"
images:
-LR4vaEIggkGekc-5ZME: "https://firebasestorage.googleapis.com/v0/b/hon..."
-LR4vaENC-IsePibQYxY: "https://firebasestorage.googleapis.com/v0/b/hon..."
name: "Thành Trung"
time: 1541992768776.3628
type: "Funny"
timestamp: 1540276959924
I removed the timestamp node and transferred it along the children node. Now you can fetch the posts with this.
ref.child("Posts").observe(.childAdded) { (snapshot) in
var post = Post()
let val = snapshot.value as! [String: Any]
post.name = val["name"] as? String
self.ref.child("Posts").child(snapshot.key).child("images").observeSingleEvent(of: .value, with: { (snap) in
post.imagesString = [String]()
for image in snap.children.allObjects as! [DataSnapshot] {
post.imagesString?.append(image.value as! String)
print("images \(image.value)")
}
list.append(post)
print("post \(post)")
})
If you want to order the posts you can achieve it using queryOrderedByChild("timestamp")
Add this to access your images:
guard let images = dict["images"] as? [[String: Any]] { return }
let imagesString: [String] = []
for imageDict in images {
for key in imageDict.keys {
if let imageName = imageDict[key] as? String else {
// here you access your image as you want
imagesString.append(imageName)
}
}
}
Then when creating the post object you use imagesString that we created:
let newPost = Post(avatarString: avatar, contentString: content, imagesString: imagesString, nameString: name, timeDouble: time, typeString: type)
You can fetch the images values using this
ref.child("Posts").observe(.childAdded) { (snapshot) in
self.ref.child("Posts").child(snapshot.key).observe(.childAdded, with: { (snapshot1) in
self.ref.child("Posts").child(snapshot.key).child(snapshot1.key).child("images").observe(.childAdded, with: { (snap) in
let post = new Post()
for rest in snap.children.allObjects as! [DataSnapshot] {
//append images
post.imagesString.append(rest.value)
}
post.avatarString = snapshot1.value["avatar"] as? String
...
})
})
I suggest you change the structure of your db because its nested. Refer here