Update the number of likes in Post (Firebase) - firebase-realtime-database

var postRef:DatabaseReference {
return Database.database().reference().child("posts")
}
#IBAction func LikePostTapped(_ sender: UIButton) {
postRef.observeSingleEvent(of:.value, with: { [self] (snapshot) in
if snapshot.children.allObjects is [DataSnapshot] {
count = count + 1
LikeCount.text = "\(count)"
LikeCount.textColor = UIColor.red
postRef.updateChildValues(["likes":count])
}
})
}
I am trying to update the number of likes for each post in my database. However when i click the like button its saves the number of likes in a new child node in firebase and not in the likes child node on the particular post. Here is a picture that shows what i mean.
PICTURE LINK: https://i.stack.imgur.com/64wLn.png

Related

Swift -Firebase how to observe multiple posts in tableView cells

I have a tableView that has a number of cells for each post. I need to observe changes to a couple of different properties (availability && hours) and I would like to update them in the specific cells that they relate to. This is what I came up with but I don't think it is the correct way to do it because I only need to listen for changes to the availability && hours properties.
struct Post {
var postId: String
var uid: String
var availability: Bool // this can change
var hours: String // this can change
}
var arrOfPosts = [Post]() // 1 - n posts
override viewDidLoad() {
super.viewDidLoad()
for post in arrOfPosts {
let postId = post.postId
Database....child(postId).observe( .childChanged, with: { (snapshot) in
let updatedPostId = snapshot.key
if let indexOfItem = self.arrOfPosts.firstIndex(where: { $0.postId == updatedPostId }) {
// update post in cell via batchUpdate
}
})
Database....child(postId).observe( .removed, with: { (snapshot) in
let deletedPostId = snapshot.key
if let indexOfItem = self.arrOfPosts.firstIndex(where: { $0.postId == deletedPostId }) {
// remove cell via batchUpdate
}
})
}
}
It's correct but you need to be specific in path to minimize response load that firebase adds more cost for
Database....child("\(postId)/availability")
same for hours

How to fetch specific hashtag post (updated)

I am trying to fetch specific post by users based on what category that user selects.
For example I have a collection view with multiple categories such as "Cold Shoulder, Bike Shorts, Gold"
If a user uses a hashtag #bikeshorts on a post, that post will also be featured in the category called Bike Shorts.
How can I fetch the photos that contain the hashtag #bikeshorts ?
Here is my database structure via Firebase (There are 2 post in total that use the hashtag "bike shorts" )
Here is the code I am trying now but no success
func fetchPosts() {
if trendName == "Bike Shorts" {
print("Fetching posts with the hashtag bikeshorts")
let query = HASHTAG_POST_REF.queryEqual(toValue: "bikeshorts")
query.observeSingleEvent(of: .value) { (snapshot) in
if snapshot.exists() {
let postId = snapshot.key
Database.fetchPost(with: postId, completion: { (post) in
self.posts.append(post)
self.collectionView?.reloadData()
})
}
}
}
}
UPDATE
I was able to get the post for bike shorts to fetch!
This is the code I used
func fetchPosts() {
if trendName == "Bike Shorts" {
print("Fetching posts with the hashtag bikeshorts")
HASHTAG_POST_REF.child("bikeshorts").observe(.childAdded) { (snapshot) in
let postId = snapshot.key
Database.fetchPost(with: postId, completion: { (post) in
self.posts.append(post)
self.collectionView?.reloadData()
})
}
}
}

Updating tableview without reloading the view (Swift, Firebase)

So I am trying to get all of the favourites from a database to show up in a tableview. However, when I favourite a user, it only displays one.
The structure of my database looks like:
Favourites:
UserID:
key: User 1
key: User 2
and my code:
var usersArray[UserClass]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
fetchFavourites()
}
func fetchFavourites () {
let userID = Auth.auth().currentUser?.uid
let favouriteRef = self.databaseRef.child("favourites").child(userID!)
favouriteRef.queryOrderedByKey().observe(.childAdded, with: { (snapshot) in
let favouriteID = "\(snapshot.value!)"
let usersRef = self.databaseRef.child("users")
usersRef.observe(.value, with: { (users) in
self.usersArray.removeAll()
for user in users.children {
let user = UserClass(snapshot: user as! DataSnapshot)
if favouriteID == user.uid {
self.usersArray.append(user)
}
self.tableView.reloadData()
}
})
})
}
I have tried creating another array within the function and then making the main array = to that, however it doesn't update the tableview when switching between screens. This code only works when the page view is loaded for the first time. However, I am using a back button that doesn't up date the screen.
Thanks, let me know if you want me to provide anything else.
Edited code (new problem, see below):
func fetchFavourites () {
DispatchQueue.main.async( execute: {
let userID = Auth.auth().currentUser?.uid
var tempFav = [UserClass]()
let favouriteRef = self.databaseRef.child("favourites").child(userID!)
favouriteRef.queryOrderedByKey().observe(.childAdded, with: { (snapshot) in
let favouriteID = "\(snapshot.value!)"
let usersRef = self.databaseRef.child("users")
tempFav.removeAll()
usersRef.observe(.value, with: { (users) in
self.usersArray.removeAll()
for user in users.children {
let user = UserClass(snapshot: user as! DataSnapshot)
if favouriteID == user.uid {
tempFav.append(user)
}
self.usersArray = tempFav
self.tableView.reloadData()
}
})
})
})
}
The problem has been fixed where it populates the tableview with all of the liked users and gets rid of them if I unlike them etc. However, if I unlike all of the users. The array duplicates a user twice even though it should be empty.

Wont show like until refresh of tableview - swift & Firebase

I am fetching all the posts from the users I am following like this:
func observePosts(userID: String) {
let ref = FIRDatabase.database().reference().child("Users").child(userID).child("Wall")
ref.observeEventType(.ChildAdded, withBlock: { (snapshot) in
let postId = snapshot.key
let postReference = FIRDatabase.database().reference().child("feed-items").child(postId)
postReference.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let update = Sweet(snapshot: snapshot)
self.updates.append(update)
self.updates = self.updates.reverse()
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}, withCancelBlock: nil)
}, withCancelBlock: nil)
}
THe problem is, when I click like on one of the posts, the likelabel is not updates. I have a custom class for the cell and in that I have the likeButton action and it is updating the count of likes. It just does not show in the tableView until I refresh the tableview.
How can I get it update the count in real time so I do not need to pull to refresh before I can see that I liked the post?

Follower counter not updating node in firebase

I have been trying to implement a "follow" function on my app. Essentially when a user hits the "follow" button, we run a runTransactionBlock to update integer values we are storing on Firebase database for the user and the account they are following. The issue is that I am able to update the counter for the user (say John in example below) , but I am not able to update the counter for the user I am following (say olivia in example below).
Currently the Firebase nodes look as such:
user_profiles{
UID1:{
name: john
following: 1 //code will update for my account
followers: 0
},
UID2:{
name: olivia
following: 0
followers: 0 //code will not update count for person i am trying to follow
I have referenced the following, however I am still facing issues with getting this to work. If anyone can please glance through and point me in the right direction, it would be greatly appreciated.
https://www.firebase.com/docs/ios/guide/saving-data.html
Firebase database help - Swift
Upvote/Downvote system within Swift via Firebase
var guestUIDToPass = String()
var loggedInUser = AnyObject()
#IBAction func didTapFollow(sender: AnyObject) {
following()
}
func following() {
self.loggedInUser = FIRAuth.auth()?.currentUser
//updating count for user, works perfectly
self.databaseRef.child("user_profiles").child(self.loggedInUser.uid).child("following").runTransactionBlock({
(currentData:FIRMutableData!) in
var value = currentData.value as? Int
if (value == nil) {
value = 0
}
currentData.value = value! + 1
return FIRTransactionResult.successWithValue(currentData)
})
//updating count for person user is following, doesn't update firebase
self.databaseRef.child("user_profiles").child("\(self.guestUIDToPass)").child("followers").runTransactionBlock({
(currentData:FIRMutableData!) in
var value = currentData.value as? Int
if (value == nil) {
value = 0
}
currentData.value = value! + 1
return FIRTransactionResult.successWithValue(currentData)
})
}
Try:-
let prntRef = FIRDatabase.database().reference().child("user_profiles").child(whomIFollowedUID).child("following")
prntRef.runTransactionBlock({ (following) -> FIRTransactionResult in
if let followNum = following.value as? Int{
following.value = followNum + 1
return FIRTransactionResult.successWithValue(following)
}else{
return FIRTransactionResult.successWithValue(following)
}
}, andCompletionBlock: {(error,completion,snap) in
print(error?.localizedDescription)
print(completion)
print(snap)
if !completion {
print("The value wasn't able to Update")
}else{
//Updated
}
})

Resources