Ambiguous use of 'subscript(_:)' when trying to retrieve users from my FireBase Database - swift

Like the description says I'm trying to retrieve users info from my Firebase Database and append them to my array I created but im getting the "Ambiguous use of 'subscript(_:)'" error in my for in loop
˚
func getArtist(){
let reference = Database.database().reference()
reference.child("users").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
let users = snapshot.value as! [String : AnyObject]
self.artistArray.removeAll()
for (_,value) in users {
if let artistId = value["uid"] as? String {
if artistId != Auth.auth().currentUser!.uid{
let artistShown = Artist()
if let userName = value["full_name"] as? String, let imagePath = value["urlToImage"] as? String {
artistShown.UserName = userName
artistShown.pathToImage = imagePath
artistShown.ArtistId = artistId
self.artistArray.append(artistShown)
}
}
}
}
self.ArtistView.reloadData()
})
reference.removeAllObservers()
}
˚
I've also attached A ScreenShot to show Where I'm getting the error
Error message

Related

Cant fetch from Firebase Realtime Database

I don't know why cant find how get friends Ids.
her is my code:
func fetchUsers() {
let ref = Firebase.Database.database().reference()
guard let userId = Auth.auth().currentUser?.uid else { return }
let userID = userId
ref.child("Users").child(userID).observe(.childAdded) { (snapshot) in
print("snapshot...\(snapshot)")
let user = User()
if let dictionary = snapshot.value as? [String:AnyObject]{
user.currentUserFriends = dictionary["Friends"] as? String
print("dictionary...\(user.currentUserFriends ?? "no value")")
}
}
}
and my tree from firebase is Users-Uid-Friends-friendID-true.
Solved!
ref.child("Users").child(userID!).child("Friends").observeSingleEvent(of: .value) { (snapshot) in
print("snapshot...\(snapshot)")
let dic = snapshot.value as! NSDictionary
for (key,value) in dic{
let friendsID = key
let friendBool = value
print("key is \(friendsID) and value is \(friendBool)")
let user = User()
user.currentUserFriends = key as? String
}
}

Not able to read data from Firebase realtime database

I have stored the comments under a post in firebase realtime database. The problem i have is that when i try to parse out the data from firebase i get an error that says Unexpectedly found nil while unwrapping an Optional value. So for example if i try to pront the data stored under degree, i get this nil error. But when i print "comments" instead of the "degree" i successfully fetch the data. My database structure looks like this.
func obeserveComments() {
// get auto-id of post
let commentKey = self.keyFound
let postRef = Database.database().reference().child("posts").child(commentKey)
var tempComments = [Comments]()
postRef.observe(.value, with: {(snapshot) in
if let dict = snapshot.value as? [String:Any] {
if let comments = dict["comments"] as? [String:Any] {
let degree = comments["reply degree"] as! String
// let name = comments["reply name"] as! String
// let text = comments["reply text"] as! String
// let university = comments["reply university"] as! String
// let photoURL = comments["reply url"] as! String
// let url = URL(string: photoURL)
// let timestamp = comments["timestamp"] as! Double
print(degree)
}
}
})
}
The answer by #aytroncb is a good answer, I prefer to leave Firebase data 'Firebasy' as long as possible. In other words coverting to dictionaries looses ordering and and find code like this
[String: [String: [String: Any]]]
To be very hard to read.
I prefer
let snap = snapshot.childSnapshot("comments") //snap becomes a DataSnapshot
So my solution maintains the order and leverages .childSnapshot to leave data in it's DataSnapshot form.
func readPostComments() {
let postRef = self.ref.child("posts") //self.ref points to my firebase
postRef.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
print("postId: \(postSnap.key)")
let commentsSnap = postSnap.childSnapshot(forPath: "comments") //will be a DataSnapshot
let allComments = commentsSnap.children.allObjects as! [DataSnapshot]
for commentSnap in allComments {
print(" commentId: \(commentSnap.key)")
let replyDegree = commentSnap.childSnapshot(forPath: "reply_degree").value as? String ?? "No Degree"
let replyName = commentSnap.childSnapshot(forPath: "reply_name").value as? String ?? "No Name"
print(" degree: \(replyDegree) by: \(replyName)")
}
}
})
}
EDIT
For a single post, remove the top part of the code that reads in and iterates over all posts.
func readCommentsForOnePost() {
let postRef = self.ref.child("posts")
let postCommentRef = postRef.child("post_0")
postCommentRef.observeSingleEvent(of: .value, with: { snapshot in
print("postId: \(snapshot.key)")
let commentsSnap = snapshot.childSnapshot(forPath: "comments") //will be a DataSnapshot
let allComments = commentsSnap.children.allObjects as! [DataSnapshot]
for commentSnap in allComments {
print(" commentId: \(commentSnap.key)")
let replyDegree = commentSnap.childSnapshot(forPath: "reply_degree").value as? String ?? "No Degree"
let replyName = commentSnap.childSnapshot(forPath: "reply_name").value as? String ?? "No Name"
print(" degree: \(replyDegree) by: \(replyName)")
}
})
}
Its because firebase is returning your data like this
{
"MAKFW244kdL)Cw;1": [Array of data],
"LOPSw!35pa3flAL4": [Array of data],
"ALV34VR4_A6Vn1a": [Array of data]
}
So change your initial casting of snapshot.value to this:
if let dict = snapshot.value as? [String: [String: Any]]
then loop through that new dictionary like this:
for objectJson in dict.values {
if let comments = objectJson["comments"] as? [String: [String: Any]] {
for commentJson in comments.values {
let degree = commentJson["reply_degree"] as? String
}
}
}
Update
Just read through your post again and noticed your trying to access the comments directly with a key, your first going to need to provide the PostId. Then you can use the above code to loop through the objects
let postRef = Database.database().reference().child("posts").child(postID)
alternatively I believe you can have the comments returned as a normal list by doing something like this:
let postRef = Database.database().reference().child("posts").child("\(postID)/{id}")

I am trying to query a firebase database in while the user is typing, but I keep getting this error

So I found this code to query your database while the user is still typing, but the code was outdated and I've been updating it, but there's an error that I don't know how to fix.
func findFriends(text: String) -> Void {
let ref = Database.database().reference()
ref.child("users").queryOrdered(byChild: "username").queryStarting(atValue: text).queryEnding(atValue: text+"\u{f8ff}").observe(.value, with: { snapshot in
let user = User()
let userArray = [User]()
for u in snapshot.children{
user.name = u.value!["name"] as? String
}
})
I get an error in the last line and it says:
Value of type 'Any' has no member 'value'
The elements in snapshot.children are of type Any, which doesn't have a value property. To get at the value property you need to cast u to a DataSnapshot:
for userSnapshot in snapshot.children{
let userSnapshot = userSnapshot as! DataSnapshot
guard let dictionary = userSnapshot.value as? [String: Any] else { return }
user.name = dictionary["name"] as? String
}
Alternatively, you put the cast in the loop:
for userSnapshot in in snapshot.children.allObjects as? [DataSnapshot] ?? [] {
guard let dictionary = userSnapshot.value as? [String: Any] else { return }
user.name = dictionary["name"] as? String
}

retrieving data from auto id database child

I'm kinda new on swift programming, my case is:
I have a database on firebase realtime "see picture", I want to retrieve the firstName and lastName data of a specific ID only.
for example:
When i'm at login screen and logged in using this email: "ali_y_k#hotmail.com", and when going to the next screen i want to display the firstName and lastName of this email in the text fields showing on picture
I have tried several solutions but the problem always was I can't enter the random IDs child to fetch the firstName and lastName
there is what i tried:
First
func retriveInfo () {
let databaseRef = Database.database().reference().child("User_Informations")
databaseRef.observe(.childAdded) { (snapshot) in
let snapshotValue = snapshot.value as! Dictionary<String,String>
let firstName = snapshotValue["firstName"]!
let lastName = snapshotValue["lastName"]!
let email = snapshotValue["email"]!
print(firstName,lastName,email)
}
}
This is printing all data (firstName,lastName,email) from every id
Second
func retriveInfo() {
let databaseRef = Database.database().reference().child("User_Informations")
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
let userSnap = snap as! DataSnapshot
let uid = userSnap.key //the uid of each user
let userDict = userSnap.value as! [String:AnyObject] //child data
let firstName = userDict["firstName"] as! String
let lastName = userDict["lastName"] as! String
print("key = \(uid) First Name = \(firstName), Last Name = \(lastName)")
}
})
This will print every key "Id" and all the info
Thank You in advance :)
Since you have childByAutoId you have to use query ordered and query equal.
let reference = Database.database().reference().child("User_Informations").queryOrdered(byChild: "email")
reference.queryEqual(toValue: "ali_y_k#hotmail.com").observeSingleEvent(of: .childAdded) { (snapshot) in
let dictionary = snapshot.value as! [String : Any]
let firstName = dictionary["firstName"]
print(firstName)
}
You need to use the current user id after you login
let currentUserUid = FIRAuth.auth()!.currentUser!.uid
let databaseRef = Database.database().reference().child("User_Informations/\(currentUserUid)")
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
}

Firebase: Very Slow data show on Label text

I'm trying to observe information from my firebase database and store it in a dictionary, the problem is when I try to show these data on a label it takes a lot of time about 30 seconds, can you solve it please.
#objc func fetchUser() {
let user = Auth.auth().currentUser
if let user = user {
let uid = user.uid
let email = user.email
ref?.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String : AnyObject] {
print(dictionary)
self.disName.text! = dictionary["DisplayName"] as! String
}
})
disUID.text = uid
disEmail.text = email
}
}