1 year ago
#384965
Tarun Reddy
SWIFTUI/FIREBASE: Firebase data is not being fetched/mapped correctly
https://www.loom.com/share/72e124ba35fe44489e472c1d442c751a
^^HERE IS A QUICK VIDEO WHERE I DEMO THE BUG AND THE CODE!!! ANY HELP WOULD BE EXTREMELY APPRECIATED! THANK YOU!
ISSUE: Cant fetch the list of users in realtime seamlessly.. either doesn't fetch right away or produces duplicate results.
import Firebase import FirebaseAuth import FirebaseFirestoreSwift import SDWebImageSwiftUI import SwiftUI
//THE VIEWMODEL
@MainActor
class ContactsViewModel: ObservableObject {
@Published var user: User
@Published var userRequestInboxUsers = [User]()
@Published var emergencyContactUsers = [User]()
init(user: User) {
self.user = user
self.fetchTheUsersRequests()
// self.fetchTheUsersContacts()
self.fetchContacts()
}
//this function works correctly
func fetchTheUsersRequests() {
guard let uid = user.id else { return }
let query = COLLECTION_FOLLOWERS.document(uid).collection("inbox").whereField(
"currentStatus", isEqualTo: "isPending")
query.addSnapshotListener(includeMetadataChanges: true) { snapshot, error in
if let error = error {
print("There was an error querying the inbox requests: \(error.localizedDescription)")
} else {
for request in snapshot!.documents {
COLLECTION_USERS.document(request.documentID).getDocument { snapshot, error in
if let error = error {
print("There was an error fetching the user data: \(error)")
} else {
guard let userRequestInInbox = try? snapshot?.data(as: User.self) else { return }
self.userRequestInboxUsers.append(userRequestInInbox)
}
}
}
}
}
}
//this is the first function I wrote to try and fetch the contacts
//this func works in mapping the user however it initially shows duplicate data.... I think this is because im appending instead of assigning
func fetchTheUsersContacts() {
guard let uid = user.id else { return }
let query = COLLECTION_FOLLOWERS.document(uid).collection("inbox").whereField(
"currentStatus", isEqualTo: "emergencyContact")
query.addSnapshotListener(includeMetadataChanges: true) { snapshot, error in
if let error = error {
print("There was an error querying the emergency contacts: \(error.localizedDescription)")
} else {
for userContact in snapshot!.documents {
COLLECTION_USERS.document(userContact.documentID).getDocument { snapshot, error in
if let error = error {
print("There was an error fetching the user data: \(error)")
} else {
guard let contact = try? snapshot?.data(as: User.self) else { return }
self.emergencyContactUsers.append(contact)
}
}
}
}
}
}
//this is the Second function I wrote to try and fetch the contacts
//this function doesnt duplicate the data however it doesnt properly map to my user object. It only gives me access to the users's ID
func fetchContacts() {
guard let uid = user.id else { return }
let query = COLLECTION_FOLLOWERS.document(uid).collection("inbox").whereField(
"currentStatus", isEqualTo: "emergencyContact")
query.addSnapshotListener(includeMetadataChanges: true) { snapshot, error in
guard let documents = snapshot?.documents else {
print("no contacts yet...")
return
}
self.emergencyContactUsers = documents.compactMap { (mapUser) -> User? in
print(mapUser.documentID)
return try? mapUser.data(as: User.self)
}
}
}
}
//THE USER OBJECT
struct User: Codable, Identifiable, Equatable {
//firebase uid becomes the handle
@DocumentID var id: String?
//The username cant have duplicates in the database + is how users search other users to add them to their special friends list
var fullName: String?
var userName: String?
var age: Double?
var sex: String?
var weight: Double?
var height: String?
var eyeColor: String?
var hairColor: String?
var homeAddress: String?
var identifyingFeatures: String?
var shoeSize: Double?
var phone: String?
var profileImageUrl: String?
//where the current location of the user is stored and the property called whenever a user needs to share their loco
//var location: CLLocation?
}
//THE VIEW
struct ContactsView: View {
var user: User
@ObservedObject var viewModel: ContactsViewModel
init(user: User) {
self.user = user
self.viewModel = ContactsViewModel(user: user)
}
var body: some View {
NavigationView {
ScrollView {
Rectangle()
.frame(height: UIScreen.main.bounds.height * 1 / 10)
.foregroundColor(.white)
VStack(spacing: 20) {
NavigationLink {
SearchView()
} label: {
SearchButton()
}
Divider()
NavigationLink {
UserRequestList(user: user)
} label: {
ZStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 200, height: 70)
Text("Your current requests").foregroundColor(.white)
}
}
}
Divider()
Text("Your Emergency Contacts:").bold()
.foregroundColor(.green)
.padding(.vertical)
ForEach(viewModel.emergencyContactUsers) { user in
NavigationLink {
EmergencyContactsDetailView(user: user)
} label: {
UserRequestCell(user: user)
.frame(maxWidth: .infinity)
.foregroundColor(.green)
}
}
Divider()
Rectangle()
.frame(height: UIScreen.main.bounds.height * 1 / 10)
.foregroundColor(.white)
}
}
.onAppear {
print(viewModel.emergencyContactUsers.description)
}
.navigationBarTitle("")
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
ios
firebase
firebase-realtime-database
swiftui
swiftui-list
0 Answers
Your Answer