How to get the field values in firebase cloud database? - swift

let reference = Firestore
.firestore()
.collection(FBKeys.CollectionPath.users)
.document(uid)
reference.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document?.data()
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
}
I have created a cloud database using firebase. I have collection name is "users" and I have email, favoriteArtsts, name, uid as the fields. What I want to do is I want to add more artists to the favoriteArtsts array. However, to do so, I have to first get the reference to the array. By following the firebase instructions, I was able to get the user_id. The code above is the code I have tried. The code shows all the fields. However, I don't know how to get the favoriteArtsts values only. Is there a way to get the favoriteArtsts values?

You can get a single field by doing document.get("favoriteAritsts") (notice your typo in favoriteAritsts in your screenshots.
You can also do document.data()["favoriteAritsts"]
Both of the above will give you a return type of Any? so you would need to do any optional cast of either one with as? [String]:
let array = document.get("favoriteAritsts") as? [String]

Related

Firebase/Firestore: Value of type 'DocumentReference' has no member 'get'

I am trying to access a document and get value from the fields so I can login as a user and retrieve that user data. I have the following code that will not compile because I keep getting the error 'Value of type 'DocumentReference' has no member 'get'. Please help!
Your newDoc is a DocumentReference object, which is nothing more than a reference to a (potential) document in the database.
To load the document from the database you need to call getdocument() on the reference, as shown in this snippet from the documentation:
let docRef = db.collection("cities").document("SF")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
}
The data is only available within the completion handler, as shown above. Trying to access it outside of there will lead to timing problems, as the data is loaded asynchronously.

(Swift) How to retrieve array -> mapped object data from Firestore Cloud [duplicate]

In Swift, to retrieve an array from Firestore I use:
currentDocument.getDocument { (document, error) in
if let document = document, document.exists {
let people = document.data()!["people"]
print(people!)
} else {
print("Document does not exist")
}
}
And I receive data that looks like this
(
{
name = "Bob";
age = 24;
}
)
However, if I were to retrieve the name alone, normally I'd do print(document.data()!["people"][0]["name"]).
But the response I get is Value of type 'Any' has no subscripts
How do I access the name key inside that object inside the people array?
The value returned by document.data()!["people"] is of type Any and you can't access [0] on Any.
You'll first need to cast the result to an array, and then get the first item. While I'm not a Swift expert, it should be something like this:
let people = document.data()!["people"]! as [Any]
print(people[0])
A better way of writing #Frank van Puffelen's answer would be:
currentDocument.getDocument { document, error in
guard error == nil, let document = document, document.exists, let people = document.get("people") as? [Any] else { return }
print(people)
}
}
The second line may be a little long, but it guards against every error possible.

Can I use a Swift String Variable to get a Firebase document for a user?

I am trying to read some data from my database but I only want to read the data for one user instead reading the data from all Users.
I tried using the variable userEmail to list only a certain users code.
let userEmail = String((Auth.auth().currentUser?.email)!)
func readArray() {
print(userEmail)
let docRef = Firestore.firestore().collection("users").document("\(userEmail)")
//let docRef = db.collection("cities").document("SF")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
}
}
I can get the user's information if I type out their user email as "test#gmail.com" but I know this won't work for other users with different login emails.
enter image description here
The issue fixed itself. Just had to reset my internet connection. This is very odd but it turns out that you can use variables to find your specific document.

Is is possible to store a Firestore field into a Swift file, and use the Swift file in a TableViewController?

Is it possible to extract a Firestore field (from a document), store it in a Swift file, and then use the value to create cells in a TableViewController?
The following is stored in my Firestore database:
users {
userid {
"level":0
"subjects":[""]
}
}
Can I somehow store 'subjects' into a Swift file (blank), and use this variable to make Table View cells (using rows)?
If what you are trying to do is query users for a specific user's "subjects" and store it in an array then this should work.
var db = Firestore.firestore()
let usersRef = db.collection("users").document(userid)
usersRef.getDocument { (document, error) in
if let document = document, document.exists {
let subjects = document.data()!["subjects"]
} else {
print("Document does not exist")
}
}
That subjects array can be used for your table view.

Firestore returns a Dictionary<String, Any> but I need the values as a String

I am using Firebase to get Google Cloud Vision Optical Character Recognition on an image then putting that information into a Firestore database, however when I pull the data from Firestore it is of type Dictionary. I need the values to be in a String so I can manipulate them however I can't seem to cast something of type Any to a String. I can put the values into an array but it is still an array of Any type. Here is the relevant code snippet:
db.collection("imagedata").document(puzzletest.name!).addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else{
print("error")
return
}
guard let data = document.data() else{
print("empty")
return
}
let arrayofres = Array(data.values)
print(type(of:arrayofres))
}
Here is the data I am trying to query:
Image of database:
Any guidance would be appreciated.
You can create a string from the dictionary values as below,
let string = data.values.compactMap({ $0 as? String}).reduce("", +)