How to display the result of this firebase array in a table?
I can see the result in the console, but I would like to display in a table all the elements of the firebase array?
func getMaterie() {
let db = Firestore.firestore()
let docRef = db.collection("DegreeCourses").document(userInfo.Tipocorso)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let materieArray = document.get("Materie") as? [[String: String]]
print(materieArray!)
}
}
}
}
Console
Related
I'm trying to fetch subcollection of my users document with code below
func readData(){
let userId = Auth.auth().currentUser?.uid
self.db.collection("users/\(userId)/saved").getDocuments { (snapshot, err) in
if let err = err {
print("err")
}
if let userId != nil {
for document in snapshot!.documents {
let docId = document.documentID
let cty = document.get("city") as! String
let ccode = document.get("code") as! String
let countr = document.get("country") as! String
print(cty, ccode, countr,docId)
}
}
}
but my code doesn't print anything, I don't understand the problem, documents exsist, see picture below
You're using illegal syntax with the userId check in the snapshot return but the logic flow is the bigger problem. I would recommend you check if the user is signed in before grabbing the subcollection and checking if there is a viable snapshot instead of checking the state of authentication.
func readData() {
guard let userId = Auth.auth().currentUser?.uid else {
return
}
db.collection("users/\(userId)/saved").getDocuments { (snapshot, error) in
guard let snapshot = snapshot else {
if let error = error {
print(error)
}
return
}
for doc in snapshot.documents {
guard let city = doc.get("city") as? String,
let code = doc.get("code") as? String,
let country = doc.get("country") as? String else {
continue // continue document loop
}
let docId = doc.documentID
print(city, code, country, docId)
}
}
}
How to to get the first name of the current user which is logged in.
This is how my try looks like:
var ref: DatabaseReference!
ref = Database.database().reference()
let db = Firestore.firestore()
let userID = Auth.auth().currentUser?.uid
print(userID)
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let username = value?["firstname"] as? String ?? ""
print(username)
// ...
}) { (error) in
print(error.localizedDescription)
}
Try the following:
let userId = Auth.auth().currentUser?.uid else { return }
let docRef = db.collection("users").document(userId)
docRef.getDocument(source: .cache) { (document, error) in
if let document = document {
let name = document.get("firstname")
print("Cached document data: \(name)")
} else {
print("Document does not exist in cache")
}
}
You are using cloud firestore but in your code, you are using the Realtime database. You need to check the following docs related to cloud firestore:
https://firebase.google.com/docs/firestore/quickstart
I am trying to retrieve data from a collection in my firestore database. But when print the retrieved data, it doesn't conform to the format I expected.
Here is my code to retrieve the data below :
let db = Firestore.firestore()
func loadEvents() -> [Event] {
var events = [Event]()
let decoder = JSONDecoder()
db.collection("Events").addSnapshotListener { QuerySnapshot, error in
guard let documents = QuerySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}
for doc in documents {
let dict = doc.data()
if let data = try? JSONSerialization.data(withJSONObject: dict, options: []) {
let event = try? decoder.decode(Event.self, from: data)
events.append(event!)
print(events) // Prints stuff like [Envy.Event] ...
}
}
// let events = documents.map {$0.data()}
}
return events
}
On reaching the print(events) it prints stuff like [Envy.Event]
[Envy.Event, Envy.Event]
[Envy.Event, Envy.Event, Envy.Event]
[Envy.Event, Envy.Event, Envy.Event, Envy.Event] which is not suitable data format for manipulation. I don't even understand this format; Can someone help me out ?
you are printing it wrong . you are printing the whole model class you created you need to refer the object inside the class for eg.
print(events.name) // use the object name you have in your class
print(events.location) // use the object name you have in your class
To add the data into array
Example Code:
db.collection("Events").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let list = Event(name: document.get("yourKeyName") as? String,location: document.get("yourAnotherKeyName") as? String)
events.append(list)
print(event.name)
print(event.location)
}
}
}
Hope this helps
This question already has answers here:
Wait until swift for loop with asynchronous network requests finishes executing
(10 answers)
Closed 4 years ago.
I would like to use asynchronous tasking for my app with using DispatchQueue.global().async and DispatchQueue.main.async, but it doesn't work.
I would like to get the data from firebase and then make List and pass it to closure. But in the code below, the timing completion called is first and then posts.append is called.
func retrieveData(completion: #escaping ([Post]) -> Void) {
var posts: [Post] = []
let postsColRef = db.collection("posts").order(by: "createdAt").limit(to: 3)
postsColRef.getDocuments() { (querySnapshot, error) in
if let error = error {
print("Document data: \(error)")
} else {
DispatchQueue.global().async {
for document in querySnapshot!.documents {
let data = document.data()
let userId = data["userId"] as? String
let postImage = data["postImageURL"] as? String
let createdAt = data["createdAt"] as? String
let docRef = db.collection("users").document(userId!)
docRef.getDocument() { (document, error) in
if let document = document, document.exists {
let data = document.data()!
let userName = data["userName"] as? String
let post = Post(
userId: userId!,
userName: userName!,
postImageURL: postImage!,
createdAt: createdAt!
)
print("When append called")
posts.append(post)
}
}
}
DispatchQueue.main.async {
print("When completion called")
print(posts)
completion(posts)
}
}
}
}
}
I would like to complete for loop at first, and then go to completion. Could anybody give me any idea?
I just found this question(Wait until swift for loop with asynchronous network requests finishes executing) and tried the code below and it worked. I'm sorry for everybody who checked this question. From next time, at first I'm going to search the existing questions. Thank you.
func retrieveData(completion: #escaping ([Post]) -> Void) {
var posts: [Post] = []
let postsColRef = db.collection("posts").order(by: "createdAt").limit(to: 3)
let group = DispatchGroup()
postsColRef.getDocuments() { (querySnapshot, error) in
if let error = error {
print("Document data: \(error)")
} else {
for document in querySnapshot!.documents {
group.enter()
let data = document.data()
let userId = data["userId"] as? String
let postImage = data["postImageURL"] as? String
let createdAt = data["createdAt"] as? String
//投稿に紐づくユーザーデータを取得して合わせてpostArrayに挿入
let docRef = db.collection("users").document(userId!)
docRef.getDocument() { (document, error) in
if let document = document, document.exists {
let data = document.data()!
let userName = data["userName"] as? String
let post = Post(
userId: userId!,
userName: userName!,
postImageURL: postImage!,
createdAt: createdAt!
)
posts.append(post)
group.leave()
}
}
}
group.notify(queue: .main) {
print(posts)
completion(posts)
}
}
}
}
How can I get single items from my Document in Firebase?
I can get all elements with this code:
let key = UserDefaults.standard.value(forKey: "uid") as! String
let docRef = firebaseDB.collection("user").document(key)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:))
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
}
I only wish to get the name and phone number. How can I filter my result?
FirebaseFirestore has a handy way of caching single documents:
First, you need to specify the document by it's ID:
let key = UserDefaults.standard.value(forKey: "uid") as? String ?? "Null" // Unique user key
let docRef = db.collection("user").document(key)
Get the document:
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let docData = document.data()
// Do something with doc data
} else {
print("Document does not exist")
}
}
Access the doc data:
let status = docData!["phone"] as? String ?? ""