Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RemoteConfig invalid array decoding #9980

Closed
Harryjeffs opened this issue Jul 2, 2022 · 8 comments · Fixed by #10046
Closed

RemoteConfig invalid array decoding #9980

Harryjeffs opened this issue Jul 2, 2022 · 8 comments · Fixed by #10046

Comments

@Harryjeffs
Copy link

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 13.4.1
  • Firebase SDK version: 9.2.0
  • Installation method: Swift Package Manage
  • Firebase Component: Remote Config
  • Target platform(s): iOS

[REQUIRED] Step 2: Describe the problem

Steps to reproduce:

Example XML:
RemoteConfigDefaults.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>state</key>
		<string>["yes", "no", "maybe"]</string>
	</dict>
</plist>

Fetching the data is fine however decoding runs into the following error:

DecodingError
▿ typeMismatch : 2 elements
- .0 : Swift.Array
▿ .1 : Context
- codingPath : 0 elements
- debugDescription : "Expected to decode Array but found FirebaseRemoteConfigValueDecoderHelper instead."
- underlyingError : nil

Relevant Code:

remoteConfig = RemoteConfig.remoteConfig()
let settings = RemoteConfigSettings()
remoteConfig.configSettings = settings
remoteConfig.setDefaults(fromPlist: "RemoteConfigDefaults")
do {
	config = try remoteConfig.decoded(asType: [String].self)
} catch {
	print(error)
}
@google-oss-bot
Copy link

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.
@paulb777
Copy link
Member

paulb777 commented Jul 2, 2022

@Harryjeffs Thanks for the report. It's possible that this is addressed by the recently merged #8307. We'll need to investigate.

@Harryjeffs
Copy link
Author

Thanks for tagging this @paulb777 . I have updated my project to 9.3.0 to include the changes from #8307 however the issue still occurs with the most basic setup (string array). Furthermore, the issue occurs with both the device defaults & the remote response. Unless my setup is grossly wrong but passes the firebase console JSON check.

@paulb777
Copy link
Member

@Harryjeffs Thanks for the update. We'll take a deeper look next week.

@jakekrog
Copy link
Contributor

jakekrog commented Jul 24, 2022

@Harryjeffs what's probably going on is you're using a JSON string instead of a plist array... this should work in 9.3.0:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>state</key>
		<array>
			<string>yes</string>
			<string>no</string>
			<string>maybe</string>
		</array>
	</dict>
</plist>

see also: https://github.com/firebase/firebase-ios-sdk/blob/aaeb5f43fcfeaa49340fa1be7a74ed7bfa5152bf/FirebaseRemoteConfig/Tests/Unit/Defaults-testInfo.plist

@paulb777
Copy link
Member

@jakekrog Good catch and thanks for the explanation!

@Harryjeffs Let us know if that resolves your question.

@Harryjeffs
Copy link
Author

Thanks for that @jakekrog. Unfortunately the issue lies with JSON strings (generated via firebase console)

Here is a more realistic scenario that I've encountered. The onboarding & isAppActive keys will fail to encode with the same error as above. The paywall key correctly encodes, along with the child array (features).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>isAppActive</key>
	<string>["yes", "no", "maybe"]</string>
	<key>onboarding</key>
	<string>[{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":"Next"},{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":null},{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":null}]</string>
	<key>paywall</key>
	<string>{"title":"Upgrade Today!","subtitle":"Start your %d day free trial today","ctaText":"Unlock Now","features":[{"systemImage":"camera","description":"Lorum Ipsum"},{"systemImage":"lock.open.fill","description":"Lorum Ipsum"},{"systemImage":"xmark","description":"Lorum Ipsum"}],"legal":{"title":"More information visit our /n Terms and Conditions","linkSubString":"Terms and Conditions","subStringLink":"https://apple.com"}}</string>
</dict>
</plist>

One workaround I tried was converting onboarding to an object, though this yielded the same error.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>isAppActive</key>
	<string>["yes", "no", "maybe"]</string>
	<key>onboarding</key>
	<string>{ "titles": [{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":"Next"},{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":null},{"title":"Lorem ipsum","imageName":"pencil","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit","advanceButtonTitle":null}]}</string>
	<key>paywall</key>
	<string>{"title":"Upgrade Today!","subtitle":"Start your %d day free trial today","ctaText":"Unlock Now","features":[{"systemImage":"camera","description":"Lorum Ipsum"},{"systemImage":"lock.open.fill","description":"Lorum Ipsum"},{"systemImage":"xmark","description":"Lorum Ipsum"}],"legal":{"title":"More information visit our /n Terms and Conditions","linkSubString":"Terms and Conditions","subStringLink":"https://apple.com"}}</string>
</dict>
</plist>

The code is the same as the original issue but hopefully, this helps with debugging.

@paulb777
Copy link
Member

Thanks for your patience @Harryjeffs.

I've reproduced the issue and confirmed that the Codable implementation does not support array and dictionary defaults set by a plist. I'm working on a fix and hope to have a PR up later this week.

In the meantime, you can use the non-Codable APIs as a workaround.

Thanks for your persistence in helping us understand the issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.