Skip to content

Commit 9fa2ac9

Browse files
Update fetch to utilize latest custom signals (#6582)
When we update custom signals using setCustomSignals, the latest custom signals are not retrieved in the subsequent fetch. Currently, we are required to reload the app to fetch them. Link to the bug: [Fetch uses stale custom signal values](https://b.corp.google.com/issues/381353888)
1 parent 17cc491 commit 9fa2ac9

File tree

5 files changed

+67
-35
lines changed

5 files changed

+67
-35
lines changed

firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,7 @@ ConfigFetchHttpClient getFrcBackendApiClient(
262262
apiKey,
263263
namespace,
264264
/* connectTimeoutInSeconds= */ sharedPrefsClient.getFetchTimeoutInSeconds(),
265-
/* readTimeoutInSeconds= */ sharedPrefsClient.getFetchTimeoutInSeconds(),
266-
/* customSignals= */ sharedPrefsClient.getCustomSignals());
265+
/* readTimeoutInSeconds= */ sharedPrefsClient.getFetchTimeoutInSeconds());
267266
}
268267

269268
@VisibleForTesting

firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ private FetchResponse fetchFromBackend(
384384
frcSharedPrefs.getLastFetchETag(),
385385
customFetchHeaders,
386386
getFirstOpenTime(),
387-
currentTime);
387+
currentTime,
388+
frcSharedPrefs.getCustomSignals());
388389

389390
if (response.getFetchedConfigs() != null) {
390391
// Set template version in metadata to be saved on disk.

firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ public class ConfigFetchHttpClient {
9494
private final String apiKey;
9595
private final String projectNumber;
9696
private final String namespace;
97-
Map<String, String> customSignalsMap;
9897
private final long connectTimeoutInSeconds;
9998
private final long readTimeoutInSeconds;
10099

@@ -108,16 +107,14 @@ public ConfigFetchHttpClient(
108107
String apiKey,
109108
String namespace,
110109
long connectTimeoutInSeconds,
111-
long readTimeoutInSeconds,
112-
Map<String, String> customSignalsMap) {
110+
long readTimeoutInSeconds) {
113111
this.context = context;
114112
this.appId = appId;
115113
this.apiKey = apiKey;
116114
this.projectNumber = extractProjectNumberFromAppId(appId);
117115
this.namespace = namespace;
118116
this.connectTimeoutInSeconds = connectTimeoutInSeconds;
119117
this.readTimeoutInSeconds = readTimeoutInSeconds;
120-
this.customSignalsMap = customSignalsMap;
121118
}
122119

123120
/** Used to verify that the timeout is being set correctly. */
@@ -187,7 +184,8 @@ FetchResponse fetch(
187184
String lastFetchETag,
188185
Map<String, String> customHeaders,
189186
Long firstOpenTime,
190-
Date currentTime)
187+
Date currentTime,
188+
Map<String, String> customSignalsMap)
191189
throws FirebaseRemoteConfigException {
192190
setUpUrlConnection(urlConnection, lastFetchETag, installationAuthToken, customHeaders);
193191

@@ -196,7 +194,11 @@ FetchResponse fetch(
196194
try {
197195
byte[] requestBody =
198196
createFetchRequestBody(
199-
installationId, installationAuthToken, analyticsUserProperties, firstOpenTime)
197+
installationId,
198+
installationAuthToken,
199+
analyticsUserProperties,
200+
firstOpenTime,
201+
customSignalsMap)
200202
.toString()
201203
.getBytes("utf-8");
202204
setFetchRequestBody(urlConnection, requestBody);
@@ -307,7 +309,8 @@ private JSONObject createFetchRequestBody(
307309
String installationId,
308310
String installationAuthToken,
309311
Map<String, String> analyticsUserProperties,
310-
Long firstOpenTime)
312+
Long firstOpenTime,
313+
Map<String, String> customSignalsMap)
311314
throws FirebaseRemoteConfigClientException {
312315
Map<String, Object> requestBodyMap = new HashMap<>();
313316

firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ public void fetch_firstFetch_includesInstallationAuthToken() throws Exception {
202202
/* lastFetchETag= */ any(),
203203
/* customHeaders= */ any(),
204204
/* firstOpenTime= */ any(),
205-
/* currentTime= */ any());
205+
/* currentTime= */ any(),
206+
/* customSignals= */ any());
206207
}
207208

208209
@Test
@@ -401,7 +402,8 @@ public void fetch_gettingFetchCacheFails_doesNotThrowException() throws Exceptio
401402

402403
@Test
403404
public void fetch_fetchBackendCallFails_taskThrowsException() throws Exception {
404-
when(mockBackendFetchApiClient.fetch(any(), any(), any(), any(), any(), any(), any(), any()))
405+
when(mockBackendFetchApiClient.fetch(
406+
any(), any(), any(), any(), any(), any(), any(), any(), any()))
405407
.thenThrow(
406408
new FirebaseRemoteConfigClientException("Fetch failed due to an unexpected error."));
407409

@@ -766,6 +768,30 @@ public void getInfo_hitsThrottleLimit_throttledStatus() throws Exception {
766768
.isEqualTo(firstFetchedContainer.getFetchTime());
767769
}
768770

771+
@Test
772+
public void fetch_usesLatestCustomSignals() throws Exception {
773+
Map<String, String> customSignals =
774+
ImmutableMap.of(
775+
"subscription", "premium",
776+
"age", "20");
777+
sharedPrefsClient.setCustomSignals(customSignals);
778+
fetchCallToHttpClientUpdatesClockAndReturnsConfig(firstFetchedContainer);
779+
fetchHandler.fetch();
780+
781+
verify(mockBackendFetchApiClient)
782+
.fetch(
783+
any(HttpURLConnection.class),
784+
/* instanceId= */ any(),
785+
/* instanceIdToken= */ any(),
786+
/* analyticsUserProperties= */ any(),
787+
/* lastFetchETag= */ any(),
788+
/* customHeaders= */ any(),
789+
/* firstOpenTime= */ any(),
790+
/* currentTime= */ any(),
791+
/* customSignals= */ eq(sharedPrefsClient.getCustomSignals()));
792+
assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(customSignals);
793+
}
794+
769795
private ConfigFetchHandler getNewFetchHandler(AnalyticsConnector analyticsConnector) {
770796
ConfigFetchHandler fetchHandler =
771797
spy(
@@ -811,7 +837,8 @@ private void setBackendResponseConfigsTo(ConfigContainer container) throws Excep
811837
/* lastFetchETag= */ any(),
812838
/* customHeaders= */ any(),
813839
/* firstOpenTime= */ any(),
814-
/* currentTime= */ any());
840+
/* currentTime= */ any(),
841+
/* customSignals= */ any());
815842
}
816843

817844
private void setBackendResponseToNoChange(Date date) throws Exception {
@@ -823,7 +850,8 @@ private void setBackendResponseToNoChange(Date date) throws Exception {
823850
/* lastFetchETag= */ any(),
824851
/* customHeaders= */ any(),
825852
/* firstOpenTime= */ any(),
826-
/* currentTime= */ any()))
853+
/* currentTime= */ any(),
854+
/* customSignals= */ any()))
827855
.thenReturn(FetchResponse.forBackendHasNoUpdates(date, firstFetchedContainer));
828856
}
829857

@@ -838,7 +866,8 @@ private void fetchCallToBackendThrowsException(int httpErrorCode) throws Excepti
838866
/* lastFetchETag= */ any(),
839867
/* customHeaders= */ any(),
840868
/* firstOpenTime= */ any(),
841-
/* currentTime= */ any());
869+
/* currentTime= */ any(),
870+
/* customSignals= */ any());
842871
}
843872

844873
/**
@@ -919,7 +948,8 @@ private void verifyBackendIsCalled() throws Exception {
919948
/* lastFetchETag= */ any(),
920949
/* customHeaders= */ any(),
921950
/* firstOpenTime= */ any(),
922-
/* currentTime= */ any());
951+
/* currentTime= */ any(),
952+
/* customSignals= */ any());
923953
}
924954

925955
private void verifyBackendIsCalled(Map<String, String> userProperties, Long firstOpenTime)
@@ -933,7 +963,8 @@ private void verifyBackendIsCalled(Map<String, String> userProperties, Long firs
933963
/* lastFetchETag= */ any(),
934964
/* customHeaders= */ any(),
935965
/* firstOpenTime= */ eq(firstOpenTime),
936-
/* currentTime= */ any());
966+
/* currentTime= */ any(),
967+
/* customSignals= */ any());
937968
}
938969

939970
private void verifyBackendIsNeverCalled() throws Exception {
@@ -946,7 +977,8 @@ private void verifyBackendIsNeverCalled() throws Exception {
946977
/* lastFetchETag= */ any(),
947978
/* customHeaders= */ any(),
948979
/* firstOpenTime= */ any(),
949-
/* currentTime= */ any());
980+
/* currentTime= */ any(),
981+
/* customSignals= */ any());
950982
}
951983

952984
private void verifyETags(@Nullable String requestETag, String responseETag) throws Exception {
@@ -959,7 +991,8 @@ private void verifyETags(@Nullable String requestETag, String responseETag) thro
959991
/* lastFetchETag= */ eq(requestETag),
960992
/* customHeaders= */ any(),
961993
/* firstOpenTime= */ any(),
962-
/* currentTime= */ any());
994+
/* currentTime= */ any(),
995+
/* customSignals= */ any());
963996
assertThat(sharedPrefsClient.getLastFetchETag()).isEqualTo(responseETag);
964997
}
965998

firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_ID;
2525
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_VERSION;
2626
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.COUNTRY_CODE;
27-
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS;
2827
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.FIRST_OPEN_TIME;
2928
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID;
3029
import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID_TOKEN;
@@ -86,10 +85,6 @@ public class ConfigFetchHttpClientTest {
8685
"etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d";
8786
private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1);
8887
private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2);
89-
private static final Map<String, String> SAMPLE_CUSTOM_SIGNALS =
90-
ImmutableMap.of(
91-
"subscription", "premium",
92-
"age", "20");
9388

9489
private Context context;
9590
private ConfigFetchHttpClient configFetchHttpClient;
@@ -110,8 +105,7 @@ public void setUp() throws Exception {
110105
API_KEY,
111106
DEFAULT_NAMESPACE,
112107
/* connectTimeoutInSeconds= */ 10L,
113-
/* readTimeoutInSeconds= */ 10L,
114-
/* customSignals= */ SAMPLE_CUSTOM_SIGNALS);
108+
/* readTimeoutInSeconds= */ 10L);
115109

116110
hasChangeResponseBody =
117111
new JSONObject()
@@ -244,8 +238,6 @@ public void fetch_setsAllElementsOfRequestBody_sendsRequestBodyToServer() throws
244238
assertThat(requestBody.get(FIRST_OPEN_TIME)).isEqualTo(firstOpenTimeIsoString);
245239
assertThat(requestBody.getJSONObject(ANALYTICS_USER_PROPERTIES).toString())
246240
.isEqualTo(new JSONObject(customUserProperties).toString());
247-
assertThat(requestBody.getJSONObject(CUSTOM_SIGNALS).toString())
248-
.isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString());
249241
}
250242

251243
@Test
@@ -324,8 +316,7 @@ public void fetch_setsTimeouts_urlConnectionHasTimeouts() throws Exception {
324316
API_KEY,
325317
DEFAULT_NAMESPACE,
326318
/* connectTimeoutInSeconds= */ 15L,
327-
/* readTimeoutInSeconds= */ 20L,
328-
/* customSignals= */ SAMPLE_CUSTOM_SIGNALS);
319+
/* readTimeoutInSeconds= */ 20L);
329320
setServerResponseTo(noChangeResponseBody, SECOND_ETAG);
330321

331322
fetch(FIRST_ETAG);
@@ -353,7 +344,8 @@ private FetchResponse fetch(String eTag) throws Exception {
353344
eTag,
354345
/* customHeaders= */ ImmutableMap.of(),
355346
/* firstOpenTime= */ null,
356-
/* currentTime= */ new Date(mockClock.currentTimeMillis()));
347+
/* currentTime= */ new Date(mockClock.currentTimeMillis()),
348+
/* customSignals= */ ImmutableMap.of());
357349
}
358350

359351
private FetchResponse fetch(String eTag, Map<String, String> userProperties, Long firstOpenTime)
@@ -366,7 +358,8 @@ private FetchResponse fetch(String eTag, Map<String, String> userProperties, Lon
366358
eTag,
367359
/* customHeaders= */ ImmutableMap.of(),
368360
firstOpenTime,
369-
new Date(mockClock.currentTimeMillis()));
361+
new Date(mockClock.currentTimeMillis()),
362+
/* customSignals= */ ImmutableMap.of());
370363
}
371364

372365
private FetchResponse fetch(String eTag, Map<String, String> customHeaders) throws Exception {
@@ -378,7 +371,8 @@ private FetchResponse fetch(String eTag, Map<String, String> customHeaders) thro
378371
eTag,
379372
customHeaders,
380373
/* firstOpenTime= */ null,
381-
new Date(mockClock.currentTimeMillis()));
374+
new Date(mockClock.currentTimeMillis()),
375+
/* customSignals= */ ImmutableMap.of());
382376
}
383377

384378
private FetchResponse fetchWithoutInstallationId() throws Exception {
@@ -390,7 +384,8 @@ private FetchResponse fetchWithoutInstallationId() throws Exception {
390384
/* lastFetchETag= */ "bogus-etag",
391385
/* customHeaders= */ ImmutableMap.of(),
392386
/* firstOpenTime= */ null,
393-
new Date(mockClock.currentTimeMillis()));
387+
new Date(mockClock.currentTimeMillis()),
388+
/* customSignals= */ ImmutableMap.of());
394389
}
395390

396391
private FetchResponse fetchWithoutInstallationAuthToken() throws Exception {
@@ -402,7 +397,8 @@ private FetchResponse fetchWithoutInstallationAuthToken() throws Exception {
402397
/* lastFetchETag= */ "bogus-etag",
403398
/* customHeaders= */ ImmutableMap.of(),
404399
/* firstOpenTime= */ null,
405-
new Date(mockClock.currentTimeMillis()));
400+
new Date(mockClock.currentTimeMillis()),
401+
/* customSignals= */ ImmutableMap.of());
406402
}
407403

408404
private void setServerResponseTo(JSONObject requestBody, String eTag) {

0 commit comments

Comments
 (0)