Retrieve last child from child node firebase realtime database swift 4 - ios

This is my firebase realtime database
Image link
This is the snippet i am using its always returning nil
let rootRef = Database.database().reference()
rootRef.child("POSTS").queryLimited(toLast: 1).observeSingleEvent(of: .value) { (myDataSnap) in
let value = myDataSnap.value as? NSDictionary
print(value as? Any)
}

If you are trying to access Id and Id's can be anything other than 0.
Than you can try the snippet below
let Key = rootRef.child("POSTS").childByAutoId().key
rootRef.child("POSTS").child(Key!).setValue(postData.toDictionary()){
(error:Error?, ref:DatabaseReference) in
if let error = error {
print("Data could not be saved: \(error).")
} else {
//do stuff
}
}

Use .childAdded or childChanged instead of .value, this might solve it
let rootRef = Database.database().reference()
rootRef.child("POSTS").queryLimited(toLast: 1).observeSingleEvent(of: .childChanged) { (myDataSnap) in
let value = myDataSnap.value as? NSDictionary
print(value as? Any)
}

Related

Firebase retuns incored snapshot swift

I have a firebase chat application and I am trying to get user credentials but I am getting wrong values from the firebase in my console
that is what my ref and snapshot is and when I decide to print this in the console I get this
CREDENTiL data ref Optional({
"cc71128f-99a7-4435-879b-b1d0c7ce9c37" = {
location = "-Lav1QzhaoRMGAJHy8nQ";
};
})
CREDENTiL data ref Optional({
email = "adie.olalekan#max.ng";
name = "Olalekan Adie";
profilePicLink = "http://www.freeiconspng.com/uploads/profile-icon-9.png";
})
this is my code
self.allUserRef?.observe(.childAdded, with: { (snapshot) in
let id = snapshot.key
print("CREDENTiL data ref \(snapshot.value)")
if let data = snapshot.value as? [String: AnyObject] {
if snapshot.hasChild("credentials") {
print("CREDENTiL data \(data)")
if let credentials = data["credentials"]! as? [String: AnyObject] {
print("CREDENTiL \(credentials)")
if id != exceptID {
let userInfo = ChatUser(dictionary: data as NSDictionary)
}
}
}
}
})
Any help would be appreciated
let refer = Database.database().reference()
refer.child("chatUsers").child("your uid").observe(.childAdded, with: { (snapshot) in
let id = snapshot.value//your snapshot
if((((snapshot.value as! NSDictionary).allKeys) as! NSArray).contains("credentials"))
{
print("credentials",snapshot.value)
}
})
Please try above code to get your credentials as snapshot.

Firebase snapshot returns null

Hi guys I have been using firebase to write and read values from the database. It was working awesome until I wrote a function to retrieve values or products stored using swift in the following way.
Here is my code
func retrieveLiveUrlFor(product: Product){
if let path = product.prodRef{
print("Looking for : \(path)")
var liveUrl = ""
let ref = Database.database().reference(withPath: path)
ref.observe(. value, with: {
snapshot in
print("Snap : \(snapshot.value)")
if snapshot.exists(){
print("Snap : \(snapshot.value)")
let dic = snapshot.value as? NSDictionary
if dic != nil{
let url = dic?["liveUrl"] as? String
print("Url is here")
if url != nil{
print("URL is not nil")
liveUrl = url as! String
}
}
}
if (self.productdelegate != nil){
print("Calling Product delegate")
self.productdelegate?.liveUrlObtained!(liveUrl: liveUrl)
}
})
}
}
And this is the value of the path that I am trying to retrieve
Products/Live/Global/WpMvDJZUclRlfHFJsSlBEbi0jHf1
And here is the snap of the firebase database
The snapshot.value alwasy returns null in swift.
When I print using
print("Snap: \(snapshot.value)")
It prints the following
Snap : Optional()
Please guide me what I am doing wrong so that I can get to it.
If you are observing using the .value event, then a return of snapshot.value as nil means that the snapshot value does not exist at that reference. Try printing the snapshot as a whole and the snapshot.key
ideally the reference you need is
let ref = Database.database.reference().child("Products").child("Live").child("Global").child("WpMvDJZUclRlfHFJsSlBEbi0jHf1")
The observer would function like this:
ref.observe(.value) {(snapshot) in
print(snapshot.value!)
}

How to retrieve data from current User in Firebase using Swift?

I am trying to get current users firstname from firebase using swift code. Below is my JSON file and swift code. But it's not retrieving first name. Please suggest
Json:
Swift code:
if FIRAuth.auth()?.currentUser != nil{
let queryRef = FIRDatabase.database().reference().child("expatsappmembers")
let userID : String = (FIRAuth.auth()?.currentUser?.uid)!
print("Current user ID is" + userID)
queryRef.child("uid").child(userID).observeSingleEvent(of: .value, with: {(snapshot) in
print(snapshot.value)
let userName = (snapshot.value as! NSDictionary)["firstname"] as! String
print(userName)
})
}
It is slightly different to get a value from Firebase in Swift 3
the proper way to do it is:
ref.child("expatsappmembers").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let firstName = value?["firstname"] as? String
// ...
}) { (error) in
print(error.localizedDescription)
}

Retrieving only current user's child values from Firebase

Edit, update at bottom, still having issues
I have my users stored in Firebase like this - each user's values are stored under their uid (FIRAuth.auth()?.currentUser?.uid):
"users" : {
"tzfHgGKWLEPzPU9GvkO4XE1QKy53" : {
"gender" : "male",
"handle" : "TestHandle2",
"name" : "Timothy",
"profilePicture" : "https://graph.facebook.com/*removed*/picture?type=large&return_ssl_resources=1"
}
}
Now to get the user's info (to set it to my User object to use around the app), I have this function:
func getUserInfo() {
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users")
// How to get specific user (current user only)??
userRef.observeSingleEvent(of: .value, with: { (snapshot) in
let users = snapshot.value as! [String: Dictionary<String, String>]
for (key, value) in users {
guard let name = value["name"] else {print("Error getting user name"); return}
guard let handle = value["handle"] else {print("Error getting user handle"); return}
guard let gender = value["gender"] else {print("Error getting user gender"); return}
guard let profilePicture = value["profilePicture"] else {print("Error getting user profilePicture"); return}
print("\n\nName: \(name)\nHandle: \(handle)\nGender: \(gender)\nProfile Picture: \(profilePicture)\n\n")
}
})
}
However this returns the values for all the users in the DB - I only want to get the values for the current user.
What can I add/change to this function to ensure that it only retrieves the values for the current user, and not all users? Also (I can make a separate question if necessary but it seems to be relevant here), is this structure of storing each user's values as children of their UID a good way to do it? I noticed a lot of the time in other examples that they are stored under a childByAutoId instead. I'm not sure what advantage that would have.
Thanks for any help!
EDIT:
If I add another child (uid) to the end of the reference and then cast as a [String : AnyObject] dictionary, I can get the current users values, but parsing it seems to be an issue.
func getUserInfo() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {print("Error getting user UID"); return}
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(uid)
self.currentUser?.uid = uid
userRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let usersDict = snapshot.value as? [String : AnyObject] {
print(usersDict)
for user in usersDict {
// guard let name = user.value(forKey: "name") else {print("Error getting user name"); return}
// guard let handle = user.value(forKey: "handle") else {print("Error getting user handle"); return}
// guard let gender = user.value(forKey: "gender") else {print("Error getting user gender"); return}
// guard let profilePicture = user.value(forKey: "profilePicture") else {print("Error getting user profilePicture"); return}
// print("\n\nName: \(name)\nHandle: \(handle)\nGender: \(gender)\nProfile Picture: \(profilePicture)\n\n")
}
}
})
}
I get an error on each of the user.value(forKey) lines, stating "cannot call value of non-function type AnyObject".
If I print(user.value) inside the loop I get all of the current user's values back perfectly. I just can't specify them individually.
You need to add another child to your userRef
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(uid)
First get UID of the current user,
let currentUid = FIRAuth.auth()?.currentUser?.uid
then replace this database reference,
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users")
with this,
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(currentUid)
:-)
it's easier than you think :-)
let userRef: FIRDatabaseReference = FIRDatabase.database().reference().child("users").child(FIRAuth.auth()?.currentUser?.uid)
Here's how I do my load of the users info,
First, I created a NSObject Class called User...
import UIKit
class User: NSObject {
// Add Whatever Child values of the user you have here
var email: String?
var nickname: String?
}
Then I called
func GetUserInfo() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
FIRDatabase.database().reference().child("users").child(uid)
.observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = User()
user.setValuesForKeys(dictionary)
print(user.nickname!)
}, withCancel: nil)
}
Don't know if this helps or not..

Retrieving and Reading Data as NSArray from Firebase (Swift 3)

I'm working through a course on Udemy to build a chat app with Firebase, Backendless, and Swift. All of the issues (it was written for Swift 2 not 3) I've been able to resolve myself, but this one has me stumped. This function is supposed to retrieve data from the Firebase database, and apparently it was supposed to retrieve it as an NSArray, but it now retrieves it as an NSDictionary, which is making a huge list of errors in the other functions because it's not expecting a dictionary.
func loadRecents() {
firebase.childByAppendingPath("Recent").queryOrderedByChild("userId").queryEqualToValue(currentUser.objectId).observeEventType(.Value, withBlock: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let sorted = (snapshot.value.allValues as NSArray).sortedArrayUsingDescriptors([NSSortDescriptior(key: "date", ascending: false)])
}
})
}
I've updated to Swift 3 as far as:
func loadRecents() {
ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let values = snapshot.value as! NSDictionary
}
})
}
Of course, using as! NSArray does not work. Would very much appreciate it if anyone can suggest a method to update this to use Swift 3, sort it by a value in the data, and be able to access it later on. Thanks!
func loadRecents() {
ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let values = snapshot.value as! [String:AnyObject]
}
})}
or you can use also let values = snapshot.value as! [Any]
Hope this will help you, try this code:
func loadRecents() {
let ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
guard let mySnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] else { return }
for snap in mySnapshot {
if let userDictionary = snap.value as? [String: Any] {
print("This is userKey \(snap.key)")
print("This is userDictionary \(userDictionary)")
}
}
})
}

Resources