Skip to content

Standardize support for Firebase products that integrate with Remote Config. #2222

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

Merged
merged 7 commits into from
Jan 20, 2021

Conversation

vic-flair
Copy link
Contributor

No description provided.

@googlebot googlebot added the cla: yes Override cla label Dec 2, 2020
@vic-flair vic-flair requested a review from danasilver December 2, 2020 19:26
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 2, 2020

Coverage Report

Affected SDKs

  • firebase-config

    SDK overall coverage changed from 88.50% (2c088d7) to 88.58% (e28bccdd) by +0.08%.

    Filename Base (2c088d7) Head (e28bccdd) Diff
    Personalization.java 88.24% 90.91% +2.67%

Test Logs

Notes

HTML coverage reports can be produced locally with ./gradlew <product>:checkCoverage.
Report files are located at <product-build-dir>/reports/jacoco/.

Head commit (e28bccdd) is created by Prow via merging commits: 2c088d7 64f38af.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 2, 2020

Binary Size Report

Affected SDKs

  • firebase-config

    Type Base (2c088d7) Head (e28bccdd) Diff
    aar 70.8 kB 71.5 kB +654 B (+0.9%)
    apk (aggressive) 91.1 kB 91.1 kB +16 B (+0.0%)
    apk (release) 718 kB 719 kB +292 B (+0.0%)

Test Logs

Notes

Head commit (e28bccdd) is created by Prow via merging commits: 2c088d7 64f38af.

@vic-flair vic-flair changed the title Add support for other Firebase products to integrate with Remote Config. Improve support for Firebase products that integrate with Remote Config. Jan 12, 2021
@vic-flair vic-flair changed the title Improve support for Firebase products that integrate with Remote Config. Standardize support for Firebase products that integrate with Remote Config. Jan 12, 2021
Copy link
Contributor

@danasilver danasilver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions and comments about usage. We should make sure we test the upgrade path between SDK versions, too.

Copy link
Contributor

@danasilver danasilver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple naming and formatting followups.

Copy link

@erikeldridge erikeldridge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems technically correct to me 👍 I dropped a couple comments re event field naming to improve readability, but since they concern naming, which can be contentious, I flagged them as minor. To avoid miscommunication, I'll defer formal approval to @danasilver, since he's the Android lead.

public static final String ARM_INDEX_LOG_KEY = "arm_index";
public static final String GROUP = "group";

public static final String ANALYTICS_PULL_EVENT_INTERNAL = "_fpc";
Copy link

@erikeldridge erikeldridge Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking (no action req'd): "_fpc" for the internal event name, and "_fpid" for the parameter name (in which to log the choice ID), aligns w the per-choice metadata design.

analyticsConnector.logEvent(ANALYTICS_ORIGIN_PERSONALIZATION, ANALYTICS_PULL_EVENT, params);
String choiceId = metadata.optString(CHOICE_ID);
if (choiceId.isEmpty()) {
return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking: this won't break EAP usage because they aren't using the SDK

return;
}

synchronized (armsCache) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding a comment explaining why we need this?

Thinking: this ensures we only log one event per param-choice pair. This map is bounded by the number of params. Choices are made on each fetch, so this isn't a long-lived cache.

}

Bundle logParams = new Bundle();
logParams.putString(ARM_KEY, key);
Copy link

@erikeldridge erikeldridge Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking: the design lists five things we want to log:

  1. Developer friendly identifier of the personalization (either the rc param, or an id customers can map back to rc param), satisfied by the arm_key field
  2. The choice that was made (a string value), satisfied by the arm_value field
  3. The group the user was in (“p13n” or “baseline”), satisfied by the group field
  4. Personalization ID, satisfied by the personalization_id field
  5. Arm index, satisfied by the arm_index field

Thinking: the external event name is arbitrary, we just need to document what it is. personalization_assignment seems self-descriptive to me 👍

Minor: renaming arm_key to something like rc_parameter would be more self-descriptive given it communicates an RC parameter.


// Constants with LOG_KEY suffix are how the corresponding ones without it are identified on
// Google Analytics.
public static final String ANALYTICS_PULL_EVENT = "personalization_assignment";
Copy link

@erikeldridge erikeldridge Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: as I commented on the iOS change, it's unclear to me what "pull" means here and below.

Also, given this whole file concerns logging to Analytics, including "analytics" in some field names, but not others is confusing. I'd vote to just omit it.

The main distinctions from my perspective are internal vs external, and "event" vs "param" (to use Analytics' "feature type" nomenclature from the event proposal).

To summarize, I'd vote to use "internal" and "external" prefixes to differentiate internal from external events, and "event" and "param" suffixes to differentiate event names from param names, eg INTERNAL_EVENT, INTERNAL_CHOICE_ID_PARAM, etc

Thinking (no action req'd): all these field names are consistent across Android and iOS 👍

analyticsConnector.logEvent(ANALYTICS_ORIGIN_PERSONALIZATION, ANALYTICS_PULL_EVENT, logParams);

Bundle internalLogParams = new Bundle();
internalLogParams.putString(CHOICE_ID_LOG_KEY, choiceId);
Copy link

@erikeldridge erikeldridge Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking: the design lists one thing we want to log:

  1. Choice ID, satisfied by the _fpid param

Thinking: the _fpc event name is correct per the events proposal.

Copy link

@andyliangdong andyliangdong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite familiar with SDK dev process, thus I'm approving from language point of view.

logParams.putString(ARM_VALUE, values.optString(key));
logParams.putString(PERSONALIZATION_ID_LOG_KEY, metadata.optString(PERSONALIZATION_ID));
logParams.putInt(ARM_INDEX_LOG_KEY, metadata.optInt(ARM_INDEX, -1));
logParams.putString(GROUP, metadata.optString(GROUP));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure where the metadata come from? is this logging server side's decision?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, from the server.

}

Bundle logParams = new Bundle();
logParams.putString(EXTERNAL_RC_PARAMETER_PARAM, rcParameter);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Much easier to read 👍

.inOrder();
assertThat(FAKE_LOGS)
.comparingElementsUsing(TO_STRING)
.containsAtLeast(INTERNAL_LOG_PARAMS_1.toString(), INTERNAL_LOG_PARAMS_2.toString())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this could be combined with the above into one statement with all four logs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't combine it if we want to check the ordering too, since it's not guaranteed that the external ones come before the internal ones.

@danasilver
Copy link
Contributor

@vic-flair Would also be good to add a test that logging a duplicate choice ID does not log to GA.

@vic-flair vic-flair merged commit a2c275c into master Jan 20, 2021
@firebase firebase locked and limited conversation to collaborators Feb 19, 2021
@kaibolay kaibolay deleted the vlum.p13n-2 branch September 15, 2022 13:32
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes Override cla size/L
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants