I have only 2 contacts saved in the simulator and in firebase for testing. But every time I logout and log back in it shows the retrieved data again. But if I kill the app by going to multitasker and log in again it olny shows those two contacts
Can you show the code you’re using to fetch the contacts and show them in this list?
It looks like you’re adding to an array that already exists, so that’s why it’s duplicating.
Paste your code in as text, rather than providing a screenshot.
To format the code nicely, place 3 back-ticks ``` on the line above your code and 3 back-ticks ``` on the line below your code. The 3 back-ticks must be the ONLY characters on the line. The back-tick character is located on the same keyboard key as the tilde character ~ (which is located below the Esc key). You can also highlight an entire code block and click the </> button on the toolbar to wrap the block for you.
This also makes it easier for anyone assisting as they can copy the code and carry out some testing.
struct ContactView: View {
@EnvironmentObject var contentViewModel: ContentViewModel
var body: some View {
NavigationView {
if contentViewModel.users.count > 0 {
List(contentViewModel.users) { contact in
VStack {
ContactRowView(user: contact)
}
.navigationTitle("Contacts")
}
.listStyle(.plain)
}
else {
Text("NO contacts")
}
}
}
}
struct ContactView_Previews: PreviewProvider {
static var previews: some View {
ContactView()
}
}
struct ContactRowView: View {
var user: User
var body: some View {
HStack(spacing: 24) {
// profile image
ZStack {
if user.photo == nil {
ZStack {
Circle()
.foregroundColor(.white)
Text(user.firstname?.prefix(1) ?? "")
.bold()
}
}
else {
let photoUrl = URL(string: user.photo ?? "")
AsyncImage(url: photoUrl) { phase in
switch phase {
case AsyncImagePhase.empty :
ProgressView()
case AsyncImagePhase.success(let image) :
image
.resizable()
.scaledToFill()
.clipShape(Circle())
case AsyncImagePhase.failure :
// display circle with frist letter of first name
ZStack {
Circle()
.foregroundColor(.white)
Text(user.firstname?.prefix(1) ?? "")
.bold()
}
}
}
}
Circle()
.stroke(Color.blue, lineWidth: 2)
}
.frame(width: 44, height: 44)
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(user.firstname ?? "")
Text(user.lastname ?? "")
}
Text(user.phone ?? "")
}
}
}
}
struct ContactRowView_Previews: PreviewProvider {
static var previews: some View {
ContactRowView(user: User())
}
}
import Contacts
class ContentViewModel: ObservableObject {
@Published var users = [User]()
private var localContacts = [CNContact]()
func getLocalContacts() {
DispatchQueue.init(label: "getting local contact").async {
let store = CNContactStore()
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
try! store.enumerateContacts(with: fetchRequest) { contacts, success in
self.localContacts.append(contacts)
DatabaseService().getPlatformUser(localContacts: self.localContacts) { platformUser in
DispatchQueue.main.async {
self.users = platformUser
}
}
}
}
}
}
to sign in email is test@test.com and password is test123
When logging in it is showing only one user after logging out it will show the other user and then when I log in again it will repeat those Contacts
Hi @riskjockeyy sorry yours got lost in the shuffle
I can look at this tomorrow or so, but if not maybe someone else can take a look!
(Just post again asking if someone can help out)
I’d be interested next to see what’s in DatabaseService.getPlatformUser
I also find it interesting how you’re creating a DispatchQueue
import Contacts
import Firebase
import SwiftUI
class DatabaseService {
func getPlatformUser(localContacts: [CNContact], completion: @escaping ([User]) -> Void ){
var platformUsers = [User]()
var lookUpPhonenumber = localContacts.map { contact in
return TextHelper.sanatizeNumber(contact.phoneNumbers.first?.value.stringValue ?? "")
}
guard lookUpPhonenumber.count > 0 else {
completion(platformUsers)
return
}
let db = Firestore.firestore()
while !lookUpPhonenumber.isEmpty {
let firstTenNumbers = Array(lookUpPhonenumber.prefix(10))
lookUpPhonenumber = Array(lookUpPhonenumber.dropLast(10))
let query = db.collection("users").whereField("phone", in: firstTenNumbers)
query.getDocuments { snapshot, error in
if error == nil && snapshot != nil {
for doc in snapshot!.documents {
if let user = try? doc.data(as: User.self){
platformUsers.append(user)
}
}
if lookUpPhonenumber.isEmpty {
completion(platformUsers)
}
}
}
}
}
}
Why do you have a while loop? Wouldn’t this be an infinite loop because lookUpPhonenumber always has values??
Or is here where you’re dropping values?
Either way I don’t think you should have Firebase code inside of a while loop, I can see that causing a lot of issues
I followed Chris’s lesson
Which one?
chat app Module 2 lesson 7