How do I take the name of the Firebase document, directly from the information of the logged in user?
Basically I have a user collection and a Degree Course collection.
When I use the func GetCorsodiLaurea
I don't want to manually insert the document name in .document ("") But I would like to automatically take the name of the document directly from the user's info The field that declares which course is connected to the user is "TipoCorso". As you can see in the Degree Courses collection there is the value of the "TipoCorso" field
Here is the code of the function and a screen of the Firebase Database:
func fetchUser() {
ref.collection("users").document(uid).getDocument { [self] (doc, err) in guard let user = doc else { return }
let Nome = user.data()?["Nome"] as! String
let Cognome = user.data()?["Cognome"] as! String
let photoURL = user.data()?["photoURL"] as! String
let Nomeintero = user.data()?["Nomeintero"] as! String
let Tipocorso = user.data()?["Tipocorso"] as! String
let Corsodilaurea = user.data()?["Corsodilaurea"] as! String
DispatchQueue.main.async {
self.userInfo = UserModel(Nome: Nome, Cognome: Cognome, photoURL: photoURL, Nomeintero: Nomeintero, Corsodilaurea: Corsodilaurea, Tipocorso: Tipocorso) }
}
}
func GetCorsodiLaurea() {
ref.collection("DegreeCourses").document("dTEzRa3qNptDssw0uBTd").getDocument { [self] (doc, err) in guard let DegreeCourses = doc else { return }
let Name = DegreeCourses.data()?["Name"] as! String
let TotalSubjects = DegreeCourses.data()?["TotalSubjects"] as! String
// [END doc_reference]
// [END collection_reference]
DispatchQueue.main.async {
self.userDegree = userDegreeModel(Name: Name, TotalSubjects: TotalSubjects)
}
}
}
CodePudding user response:
When you call the fetchUeser() function it looks like you are populating the UserModel with the specific user's Tipocorso.
So in the GetCorsodiLaurea function you can call Tipocorso member in userInfo variable.
ref.collection("DegreeCourses").document(self.userInfo.Tipocorso).getDocument { [self] (doc, err) in guard let DegreeCourses = doc else { return }
Edit: You are most likely getting the error because the fetchUsers() function hasn't completed fully (as it is waiting for Firebase to respond) but the execution has already proceeded to the GetCorsodiLaurea() function.
To fix this add, a non-escaping closure to the fetchUsers() function and call the GetCorsodiLaurea() function in the closure. This way, the compiler won't try and execute the functions asynchronously.
CodePudding user response:
Correcting the code as suggested by Amanuel Ephrem, I get an error "Document path cannot be empty."
This is the whole code:
import SwiftUI
import Firebase
import FirebaseFirestoreSwift
import FirebaseDatabase
class ProfileViewModel : ObservableObject{
@Published var userInfo = UserModel(Nome: "", Cognome: "", photoURL: "", Nomeintero: "", Corsodilaurea: "", Tipocorso: "")
@Published var userDegree = userDegreeModel(Name: "", TotalSubjects: "")
var ref = Firestore.firestore()
let uid = Auth.auth().currentUser!.uid
init() {
fetchUser()
GetCorsodiLaurea()
}
func fetchUser() {
ref.collection("users").document(uid).getDocument { [self] (doc, err) in guard let user = doc else { return }
let Nome = user.data()?["Nome"] as! String
let Cognome = user.data()?["Cognome"] as! String
let photoURL = user.data()?["photoURL"] as! String
let Nomeintero = user.data()?["Nomeintero"] as! String
let Tipocorso = user.data()?["Tipocorso"] as! String
let Corsodilaurea = user.data()?["Corsodilaurea"] as! String
DispatchQueue.main.async {
self.userInfo = UserModel(Nome: Nome, Cognome: Cognome, photoURL: photoURL, Nomeintero: Nomeintero, Corsodilaurea: Corsodilaurea, Tipocorso: Tipocorso) }
}
}
func GetCorsodiLaurea() {
ref.collection("DegreeCourses").document(self.userInfo.Tipocorso).getDocument { [self] (doc, err) in guard let DegreeCourses = doc else { return }
let Name = DegreeCourses.data()?["Name"] as! String
let TotalSubjects = DegreeCourses.data()?["TotalSubjects"] as! String
// [END doc_reference]
// [END collection_reference]
DispatchQueue.main.async {
self.userDegree = userDegreeModel(Name: Name, TotalSubjects: TotalSubjects)
}
}
}
}
But if I insert the value of the Tipocorso field, in the code:
class ProfileViewModel : ObservableObject{
@Published var userInfo = UserModel(Nome: "", Cognome: "", photoURL: "", Nomeintero: "", Corsodilaurea: "", Tipocorso: "dTEzRa3qNptDssw0uBTd")
It works, how can I fix it?