Issue Pulling UID from Firebase in Swift - ios

I've seen many youtube videos and previously answered questions on this exact subject, but for some reason my code is not working.
I want to display the user's name that is stored, but I can't pull the UID from FireBase. At this point, the user should be logged in so I don't think it's an issue of forcing the UID. Any help would be great.
Code
Firebase Data

You can get your uid as:
var ref : DatabaseReference = Database.database().reference().child("klaw-unpw").child("users")
And in your viewdidload add this code:
ref.observe(.value, with: { (snapshot) in
print(snapshot.value)
}) { (error) in
print(error)
}
But it will be good if you will start your structure with "users" instead of "klaw-unpw".
Hope it will work for you.

Related

firebase real time dB retrieving of specific data from multiple users in swift

so I'm working these days on a new project and I have a problem I can't solve, I hope someone can help me.
I'm working on an iOS app, I'm storing all user data on Firebase Real time dB.
My main goal is to get specific data from all users from particular positions,
For example:
Inside users, I have different UIDs of all the users in the dB.
In each one of them, there is a username, I would like to retrieve the username of each user.
In the future, I would like to store the location for each user under "Location". and then I would like to get all users that their location is "New-York".
I'll be glad to get some ideas on how to figure it out!
Thanks!
users
XLS37UqjasdfkKiB
username: "Donald"
ei8d4eYDafjQXyZ
username: "Barak"
etcj0lbSX5Oasfj
username: "Abdul"
rglmlG6Rasdgk5j
username: "Ron"
You can:
Load all JSON from /Users.
Loop over snapshot.children.
Then get the value of each child's username property.
These are also the most common navigation tactics when it comes to Firebase Realtime Database, so you'll apply these to pretty much any read operation.
Something like this:
Database.database().reference().child("isers").observe(.value, with: { (snapshot) in
if !snapshot.exists() {
print("No users found")
} else {
for case let userSnapshot as DataSnapshot in snapshot.children {
guard let dict = userSnapshot.value as? [String:Any] else {
print("Error")
return
}
let username = dict["username"] as? String
print(username)
}
}
})
Also see:
the documentation on reading data.
the documentation on listening for lists of data with a value event.
How to properly use queryOrderedByValue
Get Children of Children in Firebase Using Swift
And more from searching on [firebase-realtime-database][swift] children.

Removing a specific value off of firebase database

I am setting up a social media app and currently working on a way to create authentic usernames(no duplicates) for the user to enter, similar to that of Instagram.
The problem that I'm facing is that I can't find a way to delete the users previous username(in case anyone else wants to use it). The way that my database is setup for usernames is like:
Usernames
- username:"testUsername"
I have attempted to delete the code using this
let usernameRef = FIRDatabase.database().reference().child("Usernames").child("username").child(usersCurrentUsername)
usernameRef.removeValue(completionBlock: {(error, ref) in
if error != nil {
print("There was an error in removing the current username\(error?.localizedDescription)")
} else {
print(ref)
print("The child was removed")
}
})
I capture the users current username via snapshot in the viewdidload and store it in usersCurrentUsername.
Any help would be appreciated
let usernameRef = FIRDatabase.database().reference().child("Usernames").child("username");
usernameRef.removeValue();
Note that if the child of Usernames is only the username, the Usernames node will also be deleted.

Scaling with Firebase

I'm new to storing and retrieving large amounts of data from a database. I have an iOS app that stores data with Firebase and everything is working fine, but I'm worried that once there's more and more data, performance will suffer.
For example, when creating a profile, the user must choose a username that has not already been taken. In order to do this, I retrieve all of the existing usernames and check if the new username is already there. My question then is how can I test what will happen if there are thousands or even millions of existing usernames?
Thanks in advance.
Root
Profiles
[username1]
...
[username2]
...
[username3]
...
let ref = FIRDatabase.database().reference().child("Profiles").child("\(username)")
ref.observeSingleEvent(of: .value, with: {snapshot in
if snapshot.exists() {
print("user exists")
} else {
print("user not exists")
}
})

Showing posts from those users you follow - swift & firebase

I have made a following system where users can follow each other but it is not very useful at the moment. I cannot seem to get my head around how to only show the posts of the users you follow - so I am here to ask you how you would do it.
Let me just show you how the database is set up:
As you can see I have a tap called Users - in there all the users ID are stored. Whenever a user wants to follow another user, the tap Following is made and under there the user that the current user pressed follow - his/her ID is store under Following. And then the current users ID is added to the user he/she follows under Followers. Pretty simple but complicated to explain :D I hope you get where I'm going.
So now I want only to show posts of the users I am following. How would you do that? Would you do it like this: When a user is making a post it is added to his own name under a tap called Posts AND added to all the users names under PostsToFollow? I just think it would take up a lot of space in the database? Isn't there a better way to do this?
Well here is a part of my code that is getting me all of the current users followers. How can I use that code to, whenever I am creating a new post, add that to their postsToFollow?
func startObersvingDB() {
FIRDatabase.database().reference().child("Users").child(IDgotten).child("Followers").observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
var newUpdates = [FollowersStruct]()
for update in snapshot.children {
print(update)
let updateObject = FollowersStruct(snapshot: update as! FIRDataSnapshot)
newUpdates.append(updateObject)
}
self.updates = newUpdates.reverse()
self.tableView.reloadData()
}) { (error: NSError) in
print(error.description)
}
}
To Frank:
I've made this for adding the entire post to all the users that are following my user. I cannot do that because I have a like and comment button on the posts so the likes on one users posts will not be the same as other users posts and that is why I think the idea of adding the key to the post in the followers walls is great. But how do I do that?
I have made this so far, trying to accomplish what you said :-) :
let feed = Sweet(content: update, addedByUser: name!, profilePhoto: uid, likesForPost: ["user id": false], date: timePosted, category: 1, workoutComment: "", workoutTime: "")
let feedRef = FIRDatabase.database().reference().child("feed-items").childByAutoId()
feedRef.setValue(feed.toAnyObject())
FIRDatabase.database().reference().child("Users").child(uid).child("Followers").observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
var newFollowers = [FollowersStruct]()
for updateFollowers in snapshot.children {
let updateObjectFollowers = FollowersStruct(snapshot: updateFollowers as! FIRDataSnapshot)
newFollowers.append(updateObjectFollowers)
}
self.followings = newFollowers
print(self.followings.count)
for i in 0..<self.followings.count {
let followers = self.followings[i]
let feedRefFollowers = FIRDatabase.database().reference().child("Users").child(followers.Id).child("Wall").childByAutoId()
feedRefFollowers.setValue(feed.toAnyObject())
}
}) { (error: NSError) in
print(error.description)
}
Writing the post under the user's own name and all his follower's names is a typical example of fanning out the data. This indeed duplicates the data, but the benefit is that your read operations will be much faster and have significantly simpler code.
If you don't want to duplicate the entire post, you can also just write the key of the new post under each follower's "wall". Then when you need to show a list of posts for a user, you read their "wall" and client-side join each post. This is the approach taken by in our classic Firefeed example app.
Either of these approaches is a form of denormalization: duplicating part of your data to get better read performance.
I highly recommend reading this article on NoSQL data modeling and checking out our video series on Firebase for SQL developers. Oh... and this blog post on client-side fan-out also won't hurt.

How to only show friend's posts? Swift / Firebase

I just implemented a friend adding system and I'm scratching my head on how to only allow users to see friend's posts.
On my main screen where I'm displaying posts, I've got :
DataService.ds.REF_USERS.child(currentUser!).child("friends").observeSingleEventOfType(.Value) { (snapshot: FIRDataSnapshot) in
for snapshots in snapshot.children.allObjects {
let snap = snapshots as! FIRDataSnapshot
var frand = String(snap.key)
self.friendsArray.append(frand)
}
which pulls back the UID of all their friends.
I then want to search through all posts that have that UID as a child.
I figured maybe I could do a for-loop through the friendsArray with an equalTo query...? but then I'm not sure how to implement that with my currently existing query that shows back posts that I'm wanting to see :
DataService.ds.REF_POSTS.queryOrderedByChild("timestamp").queryStartingAtValue(cutoff).observeEventType(.ChildAdded, withBlock: { (snapshot:FIRDataSnapshot) in
-bunch of code that sets up my post and appends it to an array-
self.collectionView.reloadData()
})
Some of my data structure is :
users
3093098409384
friends
29834098209 : true
posts
099390234
userWhoPosted: 29834098209
So I'm pulling the friends out of the users-> friends -> UID bit, but how do I then get back posts made by those users, and THEN carry out my normal query back I'm doing?
Any guidance is appreciated.
Have a look at this article:
https://firebase.googleblog.com/2015/10/client-side-fan-out-for-data-consistency_73.html?m=1
Basically you need to "fanout" your data, that means replicating the "post" object data to multiple locations to make it easier to access.
i.e: create a "timeline" mode and under that each user's uid and under that posts from this user's followers.
Timeline: {
<user_uid>: {
<post_id>: {
// your post data
}
}
}
You do that by having each time a user submits a new post, send that post to the timeline of each of his followers.
It may sound strange but Firebase has a concept where you should duplicate data many times to make it easier to access.

Resources