Reputation: 6358
Saving my user to CoreData appears to be saving as the do catch
saving block doesn't throw any error and I actually do get the success print in it, but then when loading saved user is not found.
I noticed it because when I launch the app, at login it downloads the user from firebase every time.
Basically the whole logic is:
Login calls User.findUser()
this will look for user in CoreData
if found it will simply load user details and continue, else will call Firebase.downloadUserDetails()
that will look for user in Firebase ( in this case it means that is the first time user launch the app on the device ). If found it will download user's details and call User.saveUserDetails()
that will save user to CoreData. So at the next login it should be found. Well if I re run the app after this, User.findUser()
still won't find any users and start the whole process again.
I didn't realised it before as the User.saveUserDetails()
doesn't print any error while saving, but I added a check for any User
record in CoreData and it always shows 0
Can you see what's happening? How do I check if I properly set CoreData in AppDelegate?
This is the saving function:
static func saveUserDetails(completed: @escaping(Bool) -> (),userId: String, fcmToken: String, email: String, fullName: String, familyName: String, givenName: String, profileImage: UIImage, address: String, city: String, zipCode: String, region: String, country: String, phoneNumber: String) {
let context = AppDelegate.viewContext
//check if user is already in database
let request: NSFetchRequest<User> = User.fetchRequest()
// check for any existing records in CoreData
print("check for any existing records in CoreData")
do {
let fetchPre = try context.fetch(request)
print("saveUserDetails: Users saved in CoreData are: \(fetchPre.count)")
for user in fetchPre {
print("User id is : \(String(describing: user.userId))")
print("User name is : \(String(describing: user.fullName))")
}
} catch {
print(" Error fetching user during saving : \(error)")
}
request.predicate = NSPredicate(format: "userId == %@", userId)
// request.fetchLimit = 1
do {
let fetch = try context.fetch(request)
print("saveUserDetails: fetch is \(fetch.count)")
for value in fetch {
print(" User/saveUserDetails: checking for existing user")
if userId == value.userId {
print(" user is already saved ")
// save changes in database
// value.setValue(userId, forKey: "userId")
value.setValue(fcmToken, forKey: "fcmToken")
value.setValue(fullName, forKey: "fullName")
value.setValue(familyName, forKey: "familyName")
value.setValue(givenName, forKey: "givenName")
value.setValue(address, forKey: "address")
value.setValue(city, forKey: "city")
value.setValue(region, forKey: "region")
value.setValue(zipCode, forKey: "zipCode")
value.setValue(country, forKey: "country")
value.setValue(phoneNumber, forKey: "phoneNumber")
value.setValue(email, forKey: "email")
// return
} else {
print(" User/saveUserDetails: user is new")
//create user in database
let user = User(context: context)
user.userId = userId
user.fcmToken = fcmToken
user.fullName = fullName
user.familyName = familyName
user.givenName = givenName
user.address = address
user.zipCode = zipCode
user.city = city
user.region = region
user.country = country
user.phoneNumber = phoneNumber
user.profilePicture = UIImageJPEGRepresentation(profileImage, 1.0)! as NSData
}
do {
// save changes in database
try context.save()
print(" User/saveUserDetails: user is saved")
completed(true)
} catch {
print("Error saving user details : \(error)")
}
}
} catch {
print(" Error fetching user during saving : \(error)")
}
}
Upvotes: 0
Views: 128
Reputation: 51861
There is a logical bug in your code, right now you do
let fetch = try context.fetch(request)
for value in fetch {
if userId == value.userId {
...
} else {
...
}
Since you have a predicate for your request, "userId == %@", userId, the for
loop will only be entered if a user is found with the given id which means the else
part can never be executed and no new user created.
I
So instead of a for
loop I would suggest something like
if let user = fetch.first { //I assume the predicate means we get one or zero users back
//Handle user update
} else {
//Handle new user
}
Upvotes: 1