Retrieving Data from FireBase SWIFT - swift

I'm trying to get data out of a firebase database if the addedByUser = a value stored in the application.
With what I currently have, nothing is appearing in the table.
The firebase database looks like this:
workout1
"name"
"addedByUser"
My code looks like this:
workout3Ref.observeEventType(.Value, withBlock: { snapshot in
var newWorkout = [Workout1Info]()
for item in snapshot.children {
let createdBy = snapshot.value["addedByUser"] as? String
if createdBy == Username.sharedInstance.userDetail {
let workoutItem = Workout1Info(snapshot: item as! FDataSnapshot)
newWorkout.append(workoutItem)
}
}
self.workouts = newWorkout
self.tableView.reloadData()
})
When I get data normally without comparing if the addedByUser it normally works. Does anyone know why it isn't working?
Thanks for the help

Here's my guess based on a super vague question with some coding issues:
The createdBy is the users name or uid as a string.
The Username.sharedInstance.userDetail is an object (of some kind)
So you are comparing a String to an object that isn't a string, and that won't work.
Also, if the node you are query-ing is the /workout1 node, then you should probably name your reference workout1Ref instead of workout3Ref. That may help keep things straight in code.

While you are comaparing String createdBy with Username.sharedInstance.userDetail check your property Username.sharedInstance.userDetail also should be of String type.

Related

Store every username in the firebase database into an array variable?

Im trying to build a social media app and I have the design down and Ive been up all night trying to figure this out with no luck. I'm fairly new to coding so any help would be appreciated! Thank You! (Also my apologies if this question is already asked. Ive tried looking everywhere and couldn't find anything)
Well to start off you need to create variable which will be database reference and array where the data will be stored such as:
var Array = [String]() //array of strings (usernames)
var ref : DatabaseReference! //define type of variable
then you assign it in viewDidLoad:
ref = Database.database().reference()
using this you'll be able to access your database and load current users:
ref.child("data").observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value as? NSDictionary else {
self.listIsEmpty()
print("The user has no data in the database")
return
}
let userItem = value["Username"] as? [String] //loads the data
self.Array = userItem! //saves data to array
and then finally to write data you start by appending array which we have:
Array.append(textField.text) //reference textfield where username is or variable
ref.child("data").setValue(["Username":self.Array])

How can I read the value of a Firebase database dictionnary created using .childByAutoId() in Swift?

I have a dictionary of dictionary of Strings stored in a Firebase database. It can be seen below.
As you can see, each entry is created using .childByAutoId() and contains two variables: text and tag.
I wish to be able to go through all of the entries, and compare the value of text with a variable saved locally in my app. I have tried many ways, but cannot find any solution that works. How should I proceed?
Thank you in advance for your help.
You need to observe database at specific reference and then convert a snapshot that will be send to you. The snapshot represents a fragment of your database at given path
let dbRef = Database.database().reference().child("messages")
dbRef.observeSingleEvent(of: .value) { (snapshot) in
for message in snapshot.children{
let msg = (message as! DataSnapshot).value //message as snapshot
//now you need to cast it to your structure([String:String])
let projectObj = Message(snapshotChild: msg as! [String:String])
//and do your comparison
}
}

Get youngest child in Firebase users

I want to find the youngest user in my list of users and load their data: name, profile pict, and current job assignments. I have read the Firebase primer on querying data, but their examples don't work for me because my data is organized differently. I have an additional child layer.
This is my JSON tree in Firebase:
I've tried loading the list of users and then iterating over them to find the youngest user, but that seems like overkill. The Firebase documentation makes me think I should be able to do the query through a Firebase method, like 'queryOrderedByChild' or similar.
I've gone over the old documentation here and the new documentation here, but I'm still left wondering what to do.
So this is my workflow:
The app will find the youngest user in the list of "members" and load their name, profile pict, birthday, etc. They will choose from a list of jobs. Once that user has chosen from the lists of available jobs, the app will load the next youngest user from the list of "members", and so on until all users have been loaded and have been given the chance to select jobs.
I think a better workflow would be this:
Get youngest user by utilizing a Firebase query
Use that query to load that user (image and name)
How would I go about doing that?
EDIT #1: Code I've Tried
func loadExistingUsers(completion: #escaping ([[String : Any]]) -> ()) {
var dictionary = [[String : Any]]()
ref.child("members").observeSingleEvent(of: .value) { (snapshot: FIRDataSnapshot) in
for child in snapshot.children {
let snap = child as! FIRDataSnapshot
if let value = snap.value as? [String : Any] {
dictionary.append(value)
}
}
completion(dictionary)
}
}
And then in ViewDidLoad:
loadExistingUsers { (dictionary) in
var youngestBirthday = 19000101
var userName = "Sophie"
for item in dictionary {
let fetchedBirthday = item["birthday"] as! Int
let fetchedName = item["firstName"] as! String
if fetchedBirthday > youngestBirthday {
youngestBirthday = fetchedBirthday
userName = fetchedName
}
}
print(userName,youngestBirthday)
}
This method returns the youngest user from my list of users, but it seems like an awfully long way to go to get what I want. I have to first fetch the users from Firebase, and then parse the snapshot, then create an array, then sort the array, then get the user name. I was under the impression Firebase could do all that with one query. Am I wrong?
You can get the youngest child using this code: (since your youngest date is the largest number so I am using toLast)
ref.child("members").queryOrdered(byChild:"birthday").queryL‌​im‌​ited(toLast: 1).observeSingleEvent(of: .childAdded, with: { (snapshot) in
if let value = snapshot.value as? [String: Any] {
let name = value["firstname"] as? String
//you can do for other values as well
print(name)
}
})

When retrieving data from Firebase Database, <null> is returned: "Snap (...) <null>"

I'm a relatively new Swift programmer and am using Firebase for the first time so please excuse any misunderstandings I may have and my lack of knowledge about terminology.
I am attempting to retrieve data about a user that is stored in a database (email and username).
The code successfully finds the userID in the database. The userID is then used in order to navigate into the directory containing the username and email. It stores those values in snapshot.
For some reason, when snapshot is printed, it shows the userID but the contents of the directory (username and password) are shown as <null>. I am certain that the directory I am attempting to access and retrieve data from exists and is not empty (it contains a username and email). I wantsnapshot to store the username and email, but printing shows that it is not doing so correctly and I cannot figure out why.
here is my code block:
func checkIfUserIsLoggedIn() {
if Auth.auth().currentUser?.uid == nil {
perform(#selector(handleLogout), with: nil, afterDelay: 0)
} else {
let uid = Auth.auth().currentUser?.uid;
Database.database().reference().child("Users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
if let dictionary = snapshot.value as?[String:AnyObject] {
self.userLabel.text = dictionary["name"] as? String
}
}, withCancel: nil)
}
}
and here is what is being printed to the console:
Snap (ywU56lTAUhRpl3csQGI8W8WmQRf1) <null>
Here is the database entry I am attempting to reach and log to snapshot:
I'm a new Stack Overflow user and don't have enough experience on the site to be allowed to embed images in posts, so this is the external link
Thanks for reading, any help would be much appreciated!!
Your reference in Firebase is to "users", but you are using .child("Users") in your code. Make sure your lookup matches case to your node. I find it best to create a reference to that node and use it for writing to and reading from.
let usersRef = Database.Database().reference().child("users")
Snap (ywU56lTAUhRpl3csQGI8W8WmQRf1) <null> the portion in parenthesis refers to the end node of what you are trying to observe. In this case it refers to uid!.
if u want to get username or email then you make first the model class for
Example:-
class User: NSObject {
var name: String?
var email: String?
}
then user firebase methed observeSingleEvent
FIRDatabase.database().reference().child("user").child(uid).observeSingleEvent(of: .value, with: { (snapShot) in
if let dictionary = snapShot.value as? [String: Any]{
// self.navigationItem.title = dictionary["name"] as? String
let user = User()
user.setValuesForKeys(dictionary)
self.setUpNavigationBarWithUser(user: user)
}
})`
if it is not finding your asking values, you are asking wrong directory. check firebase db child name it must be exactly like in your code ("Users")

cloudkit enter userID as reference of a new record (in code)

I am setting an app in which a user could create records. Let's say he/she is the owner of a chatroom. Therefore there is an attribute called "admin" in the chatroom record. This attribute takes a reference which is the ID of the owner.
Here is what I tried:
CKContainer.defaultContainer().fetchUserRecordIDWithCompletionHandler({
userRecordID, error in
if error != nil {
println("caca")
} else {
println("gettin close")
let UserRecordIDToStore = NSKeyedArchiver.archivedDataWithRootObject(userRecordID)
let iDString = userRecordID.recordName as String
daMainUser.setObject(iDString, forKey: "user")
}
})
When I pass iDString as above, and I create the record (the room), its admin reference is empty. Whether I did cast iDString as a String or not.
When I pass userRecordID directly, I get an error:
'CKRecordID' is not identical to 'CKRecordValue'
I have been looking everywhere but I cannot find more information about this.
Any help would be greatly appreciated. Thank you guys!
If your user field is set up as a CKReference field, then you should set it like this:
daMainUser.setObject(CKReference(recordID: userRecordID, action: CKReferenceAction.None), forKey: "user")
In your case you do not have to create a recordID because you already have it. Otherwise you had to create it with something like:
var recordID = CKRecordID(recordName: userRecordID.recordName)