1 year ago

#384965

test-img

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

Accepted video resources