Repository: firebase/firebase-ios-sdk (language: cpp)

Issue:
RCNConfigExperiment is incorrectly flagging valid experiment JSON payloads as invalid
### [REQUIRED] Step 1: Describe your environment

  * Xcode version: 12.2
  * Firebase SDK version: 7.0.0
  * Installation method: Carthage
  * Firebase Component: RemoteConfig

### [REQUIRED] Step 2: Describe the problem

Since we upgraded from 6.18.0 to 7.0.0, we're seeing RemoteConfig log "Experiment payload could not be parsed as JSON." a bunch of times. I didn't count, but it's probably being logged once for each of our experiments. The result of this is that our A/B tests seem to have completely stopped getting updated values from the server.

#### Steps to reproduce:

It's easy to reproduce in `RCNConfigExperiement.testLoadExperimentFromTable` if you add an additional assertion to verify that the payloads were handled properly...

```objective-c
XCTAssertEqualObjects(_payloadsData, _configExperiment.experimentPayloads);
```

That assertion will fail before the fix and succeeds after the fix (see below)

#### Relevant Code:

I looked around in the `FirebaseRemoteConfig` source code and pinned down the issue (I have a PR ready to go as well).

As part of the change in this pull request (https://github.com/firebase/firebase-ios-sdk/pull/5890/files)

`RCNConfigExperiment.m` changed how it did JSON validation from... 

```Objective-c
NSError *error;
id experimentPayloadJSON = [NSJSONSerialization JSONObjectWithData:experiment options:kNilOptions error:&error];
if (!experimentPayloadJSON || error) {
```

to...

```Objective-c
if (![NSJSONSerialization isValidJSONObject:experiment]) {
```

`isValidJSONObject` is meant to receive an `NSArray` or `NSDictionary` to test if that collection can be converted into JSON data ([source]( https://developer.apple.com/documentation/foundation/jsonserialization/1418461-isvalidjsonobject)). Passing it data causes it to return false every time. The previous implementation is the correct way to test if `NSData` can be converted to JSON.


Discussion / hints:
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.
@philviso-reverb Thanks for the bug report and investigation.

@christibbs Please review the referenced change from #5890

Fix patch:
diff --git a/FirebaseRemoteConfig/CHANGELOG.md b/FirebaseRemoteConfig/CHANGELOG.md
index 83fedb1cf60..f65f58c262f 100644
--- a/FirebaseRemoteConfig/CHANGELOG.md
+++ b/FirebaseRemoteConfig/CHANGELOG.md
@@ -1,3 +1,6 @@
+# v7.5.0
+- [fixed] Fixed bug that was incorrectly flagging ABT experiment payloads as invalid. (#7184)
+
 # v7.1.0
 - [changed] Add support for other Firebase products to integrate with Remote Config. (#6692)
 
diff --git a/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m b/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m
index 3d30cd37a0e..a51190e46a6 100644
--- a/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m
+++ b/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m
@@ -74,7 +74,11 @@ - (void)loadExperimentFromTable {
     if (result[@RCNExperimentTableKeyPayload]) {
       [strongSelf->_experimentPayloads removeAllObjects];
       for (NSData *experiment in result[@RCNExperimentTableKeyPayload]) {
-        if (![NSJSONSerialization isValidJSONObject:experiment]) {
+        NSError *error;
+        id experimentPayloadJSON = [NSJSONSerialization JSONObjectWithData:experiment
+                                                                   options:kNilOptions
+                                                                     error:&error];
+        if (!experimentPayloadJSON || error) {
           FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000031",
                         @"Experiment payload could not be parsed as JSON.");
         } else {
diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m
index df37f4166ef..127c3382d2c 100644
--- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m
+++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigExperimentTest.m
@@ -109,6 +109,7 @@ - (void)testLoadExperimentFromTable {
                           _payloads[payloadIndex++][@"experimentId"]);
   }
 
+  XCTAssertEqualObjects(_payloadsData, _configExperiment.experimentPayloads);
   XCTAssertEqualObjects(_metadata, _configExperiment.experimentMetadata);
 }
 


Test patch: