Cannot assign values from functions to dictionary array Swift 4 - swift

I've encountered the following error in two different scenarios that may be related. The error is:
lldb Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
This is the code for the first scenario:
db.collection("properties").getDocuments()
{
(querySnapshot, err) in
if let err = err
{
print("Error getting documents: \(err)");
}
else
{
for document in querySnapshot!.documents {
var propertyData = [String:[String]]()
let listingType = (document.get("listingType") as! [String])
propertyData["listingType"]![0] = listingType[0]
}
}
}
I am trying to get a list of properties that I have already set in Firestore. I can print the listingType variable to the console and it successfully prints "Sale". However when I assign the variable it then gives that error.
I have experienced the same issue when using the location manager functions. If I get the user's current location coordinates, when I try to add those coordinates to a global dictionary it throws the same error. I am writing the code in Swift 4.

You can't just assign something to [0] since the array is initially nil
if propertyData["listingType"] == nil {
propertyData["listingType"] = [listingType[0]] //Create a new array with the string
} else {
propertyData["listingType"]![0] = listingType[0]
}

Related

Unable to Fetch Users Firebase Firestore

Unable to fetch list of users from firebase. print returns as [] . Code is below. Any help would be awesome!
let COLLECTION_USERS = Firestore.firestore().collection("users")
func fetchUsers() {
COLLECTION_USERS.getDocuments { snapshot, _ in
guard let documents = snapshot?.documents else {return}
self.users = documents.compactMap({try? $0.data(as: User.self)})
print(self.users)
}
I expect the 7 users that I have signed up to print that data.
If documents.count shows that you've got 7 documents, but self.users contains no elements after running the mapping, this indicates your Firestore documents can't be mapped to your Swift structs.
Please make sure that the data types on your Swift structs match the types used in your Firestore documents.
You should also use code that is more error-resilient. In your code, you explicitly drop the error parameter on the closure - you rather don't want to do this.
The following code snippet (taken from the official docs) shows how to do this.
let docRef = db.collection("cities").document("BJ")
docRef.getDocument { (document, error) in
// Construct a Result type to encapsulate deserialization errors or
// successful deserialization. Note that if there is no error thrown
// the value may still be `nil`, indicating a successful deserialization
// of a value that does not exist.
//
// There are thus three cases to handle, which Swift lets us describe
// nicely with built-in Result types:
//
// Result
// /\
// Error Optional<City>
// /\
// Nil City
let result = Result {
try document?.data(as: City.self)
}
switch result {
case .success(let city):
if let city = city {
// A `City` value was successfully initialized from the DocumentSnapshot.
print("City: \(city)")
} else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
print("Document does not exist")
}
case .failure(let error):
// A `City` value could not be initialized from the DocumentSnapshot.
print("Error decoding city: \(error)")
}
}

Get Data from firebase for swift

I have below code to get data from my firebase database
db.collection("users").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
print("starting name display")
for document in (querySnapshot?.documents)! {
let documentUserId = document.get("uid") as?String
let temp = document.data()["displayName"]
print(temp)
}
}
}
The print statement displays as optional("test name")
Why am i keep getting optional in my string. Same displays on the screen as well.
You need to un-wrap because it's an Optional. Means it could have a value or it could not have a value. So this is one method to handle it:
let temp = document.data()["displayName"] ?? ""
print(temp)
You could also use if let or guard let statements if you need to handle the cases where the value is actually empty.
Note: Take a look at the basics of swift. There is a separate section for Optionals.

Key value pair not getting added to my dictionary in Swift

I am trying to add an item to my dictionary. profileURL contains the correct value as I have seen from what the print statement gives me but for some reason the dictionary is not creating a new entry with it. Any solutions?
Here is my code:
storageRef.downloadURL(completion: {(url, error) in
if error != nil {
return
}
if let profileURL = url?.absoluteString {
print("SHOULD BE DATA HERE: ", profileURL)
databaseValues["profileUrl"] = profileURL
}
})

query if the data is found - Parse & Swift 3

I'm trying to develop an app that provide User sign up and within the UI I want to query if the email is exists or not.
The problem is since I change from swift 2 to swift 3 I got these errors
var query = PFObject(className:"User")
query.whereKey("email", equalTo: email)
query.findObjectsInBackground {
(objects, error) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects {
for object in objects {
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
/Users/**************/SignUpSenderViewController.swift:49:9:
Value of type 'PFObject' has no member 'whereKey'
/Users/i*************/SignUpSenderViewController.swift:50:9:
Value of type 'PFObject' has no member 'findObjectsInBackground'
any suggestion to solve this challenge ?
I dont know what documentation you checked but the query has to be done this way...
let query = PFQuery(className:"_User")

Cannot assign result of Parse PFQuery to instance variable of my controller Class in Swift

I'm trying to assign the value returned from the result of a Parse query to an instance variable of my view controller class called "currentProfile". Although the function retrieves the data from the server okay, it seems like it doesn't assign it to my instance variable.
This is my code :
let query = PFUser.query()
query!.getObjectInBackgroundWithId(self.profileId) {
(profile: PFObject?, error: NSError?) -> Void in
if error == nil && profile != nil {
print(profile)
self.currentProfile = (profile as? PFUser)!
} else {
print(error)
}
}
print(currentProfile)
So when I print profile the first time it prints it correctly, however when I print currentProfile outside the function it actually doesn't print anything.
If you have any idea why this is happening or know how could I fix it, it would be greatly appreciated if you could let me know.
Thanks.