Reputation: 43
Below is my data structure:
{
"posts": {
"xyz1": {
"author": "Jan",
"uid": "abc123",
},
"xyz2": {
"author": "Jenny",
"uid": "abc456",
},
}
"users": {
"abc123": {
"email": "[email protected]",
"profilePicURL": "https://firebasestorage.googleapis.com/v0/b/",
},
"abc456": {
"email": "[email protected]",
"profilePicURL": "https://firebasestorage.googleapis.com/v0/c/",
},
}
}
I want to display the list of "posts" entries in a tableview.
let postRef = ref.child("posts")
postRef.observe(.childAdded, with: { (snapshot) in
let authorText = snapshot.value!.object(forKey: "author") as! String
let userIDText = snapshot.value!.object(forKey: "uid") as! String
}) { (error) in
print(error.localizedDescription)
}
How can i use the "uid" retrieved from the above query to make a sequential query to retrieve the "profilePicURL" using the "uid" value in the "users". End goal is to display profilePic stored besides the post in the tableview.
Thank you for any help rendered.
Upvotes: 1
Views: 233
Reputation: 43
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeTableViewCell
cell.author.text = String(self.author[(indexPath as NSIndexPath).row])
let userIDText = String(self.userID[(indexPath as NSIndexPath).row])
ref.child("users").child(userIDText).observeSingleEvent(of: .value, with: { (snapshot) in
print("snaphot is \(snapshot)")
let imageLink = snapshot.value?["profileImageUrl"] as! String
self.storageRef = FIRStorage.storage().reference(forURL: imageLink)
cell.profilePic.loadImageUsingCacheWithUrlString(urlString: imageLink)
}) { (error) in
print(error.localizedDescription)
}
return cell
}
I use the following extension for UIImageView to load the image using the URL and it worked!!
let imageCache = NSCache<AnyObject, AnyObject>()
extension UIImageView {
func loadImageUsingCacheWithUrlString(urlString: String) {
self.image = nil
//check cache for image first
if let cachedImage = imageCache.object(forKey: urlString) as? UIImage {
self.image = cachedImage
return
}
//otherwise fire off a new download
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) in
//download hit an error so lets return out
if error != nil {
print(error)
return
}
DispatchQueue.main.async(execute: {
if let downloadedImage = UIImage(data: data!) {
imageCache.setObject(downloadedImage, forKey: urlString)
self.image = downloadedImage
}
})
}).resume()
}
}
Upvotes: 1
Reputation: 17132
Best idea is to store different Users into an Array of Users in which User is a Struct.
struct User {
var name: String = ""
var id: String = ""
}
Then in your ViewController you download the content from your Firebase and create Models of your User Struct.
let users: [User] = []
yourFireBaseQueryFunc() {
...
postRef.observe(.childAdded, with: { (snapshot) in
for item in snapshot {
let name = snapshot.value!.object(forKey: "author") as! String
let id = snapshot.value!.object(forKey: "uid") as! String
let user = User(name: name, id: id)
users.append(user)
}
Then for example in a tableView
you take the indexPath and one Model out of your Model Array and call a function to get the Image Link from your Firebase:
cellForRowAtIndexPath... {
let user = users[indexPath.row]
let image = getImage(user.id)
let imgURL = NSURL(string: post.picture)
cell.yourImageView.sd_setImageWithURL(imgURL)
}
And then Query for the image:
func getImage(userID: String) -> String {
var imageLink: String = ""
let ref = firebase.child("users").child(userID)
ref.observeEventType(.Value, withBlock: { snapshot in
if snapshot.exists() {
imageLink = snapshot.value!.valueForKey("profilePicURL") as! String
}
})
return imageLink
}
Upvotes: 0