0

I have a firebase function that returns an object, at first it returned one item within the object that was just a boolean. When it arrives from the .call function within the swift app, it is rather a one or a zero. Which is fine when casting the string to a boolean as it will just turn into true or false. However, adding more values on this object from the Firebase function and trying to cast the string to a string. It seems to break my Bool as well as the String also not being cast down. It seems in the docs that they always cast down to any. I know this is probably a pretty simple question to answer but can't wrap my head around it.

guard let rawTime = (result?.data as? [String: Bool])?["serverTime"] else { return }
print(rawTime)

guard let rawString = (result?.data as? [String: String])?["example"] else { return }
print(rawString)

My object coming from the firebase function is:

Optional({
    example = lala;
    serverTime = 1;
})
zak
  • 97
  • 9
  • The accepted answer is fine but a workaround to the core issue. There may be other answers if you were to include the code you're using to get the data from Firebase and also indicate if you are using the Firebase Real Time Database or Firestore. It would also be good to know how the object is 'coming from the firebase function' as there may be an issue there as well. You may be able to significantly reduce the amount of code needed to solve the issue. – Jay Nov 24 '19 at 15:10

1 Answers1

0

Your data contains 1 and lala as values, so it cannot be casted to [String: Bool] or [String: String]. Values of Swift dictionaries should have a same type. First cast it to [String: Any] and then cast rawTime from Any to Int and rawString from Any to String:


guard
  let rawTime = (result?.data as? [String: Any])?["serverTime"],
  let time = rawTime as? Int
else { return }
print(time)

guard
  let rawString = (result?.data as? [String: Any])?["example"],
  let string = rawString as? String
else { return }
print(string)
Jay Lee
  • 1,684
  • 1
  • 15
  • 27
  • 1
    Thank you that works great! Just curious though, when there was just serverTime, why was I able to cast that as a Boolean or Int, but when I added the other value on the firebase function, I couldn't cast it straight away anymore? :) – zak Nov 21 '19 at 08:13
  • @zak Probably because the type of result.data is NSDictionary. If you try “let test: NSDictionary = [“a”: 1]”, you can convert that 1 to true, and 0 to false. Swift native dictionary does not support that, e.g. [AnyHashable: Any] would result in nil. This might be relevant: https://stackoverflow.com/questions/903906/how-can-i-add-a-boolean-value-to-a-nsdictionary – Jay Lee Nov 21 '19 at 08:36