Skip to content

Conversation

@lahirumaramba
Copy link
Member

@lahirumaramba lahirumaramba commented Sep 25, 2020

  • Introduce Response Types and Public Types
  • Implement toResponseType() and toPublicType()
  • Add parameters to RemoteConfigTemplate
  • Add unit tests

Related Issue: #446

@lahirumaramba lahirumaramba force-pushed the lm-rc-parameters branch 3 times, most recently from 5e0dc25 to b5878b3 Compare September 28, 2020 19:06
@lahirumaramba lahirumaramba marked this pull request as ready for review September 28, 2020 19:10
@lahirumaramba lahirumaramba changed the title Add parameters to template Add parameters to Remote Config template Sep 28, 2020
Copy link
Contributor

@hiranya911 hiranya911 left a comment

Choose a reason for hiding this comment

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

Looks pretty good. I suggested a few renames and test additions.


public RemoteConfigParameter() {
conditionalValues = new HashMap<>();
defaultValue = ExplicitParameterValue.of("");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this default value?

Copy link
Member Author

Choose a reason for hiding this comment

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

If no default value is set (if defaultValue is null), the REST API sets the default value to an empty string. We can allow null here and add a null check in the conversion or just set it to an empty value in the ctor.

Copy link
Contributor

@hiranya911 hiranya911 left a comment

Choose a reason for hiding this comment

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

Looks great. Just a couple of suggestions.

public RemoteConfigParameter() {
conditionalValues = new HashMap<>();
defaultValue = ExplicitParameterValue.of("");
defaultValue = RemoteConfigParameterValue.of("");
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like both these should remain null until explicitly set. It's ok to let the backend choose default values for these as necessary.

Copy link
Member Author

@lahirumaramba lahirumaramba Oct 1, 2020

Choose a reason for hiding this comment

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

I see your point. Updated the code and added null checks in conversions.
I have a few concerns with setting these to null though. Isn't it recommended not to return null collections in Java? If we don't set to conditionalValues to an empty map at init, the following will throw an exception on the client side.

RemoteConfigParameter p = new RemoteConfigParameter().getConditionalValues().put("ios_en", ParameterValue.of("text")

This can be prevented with a simple null check on the client side, though.

assertTrue(parameters.containsKey("header_text"));
Map<String, RemoteConfigParameterValue> conditionalValues = parameters
.get("welcome_message_text").getConditionalValues();
RemoteConfigParameter parameter = parameters.get("welcome_message_text");
Copy link
Contributor

Choose a reason for hiding this comment

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

Also assert on header_text which has an in app default value param.

Copy link
Contributor

@egilmorez egilmorez 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 suggested edits and a few questions, thanks!


/**
* Gets the conditional values of the parameter.
* The condition name of the highest priority (the one listed first in the
Copy link
Contributor

Choose a reason for hiding this comment

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

This is interesting . . . you mean this gets all the possible values, including the one actually assigned -- for a particular client instance? -- in the top position in the map?

Copy link
Member Author

Choose a reason for hiding this comment

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

This gets all the conditional values assigned for that specific parameter. You can set a default value in a parameter to be used when all the conditional values are evaluated to false. Otherwise, the parameter will use the conditional value with the highest priority. The priority is determined by the order of the conditions are stored in the top-level conditions array of the RemoteConfigTemplate. The top-level conditions array is not part of this PR and will be added in a future PR.
https://firebase.google.com/docs/reference/remote-config/rest/v1/RemoteConfigParameter

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, thanks for the explanation. Parameter evaluation is pretty complex . . . when everything is done, I might try to start a review of our "parameters and conditions" concepts page, just to make sure it's all still accurate.


/**
* Sets the default value of the parameter.
* This is the value to set the parameter to, when none of the named conditions
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the developer actually set the value? Or does our backend logic?

Copy link
Member Author

Choose a reason for hiding this comment

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

When getting an existing template the backend will set the values for existing Parameters. If the developer wants to create and add new parameters then they can set a default value to set the parameter to, when none of the named conditions evaluate to true.

}

/**
* Sets the conditional values of the parameter.
Copy link
Contributor

Choose a reason for hiding this comment

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

Again this is maybe just my own confusion, but -- I can see how a developer might want to automate the setting of a list of conditional values. But isn't the actual value sort of set at runtime, after evaluating the conditions?

Copy link
Member Author

Choose a reason for hiding this comment

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

When creating new parameters the developer needs to add conditional values manually. The condition names in conditionalValues map must match the names in the top-level conditions array in RemoteConfigTemplate. Otherwise, the API will throw a condition does not exist error.

}

/**
* Represents an in-app-default parameter value.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggest removing the hyphen between app and default.

}

/**
* The DTO for parsing Remote Config parameter value responses from the Remote Config service.
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should spell out "Data Transfer Object" -- that's what this is, right? :)

I searched and couldn't immediately find a single other instance of "DTO" in docs/reference/

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the classes in internal packages do not show up in the docs. I agree though Data Transfer Object makes more sense. I will update the comment here. Thanks!!

Copy link
Contributor

@egilmorez egilmorez left a comment

Choose a reason for hiding this comment

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

Looks good Lahiru, thanks!

Copy link
Contributor

@hiranya911 hiranya911 left a comment

Choose a reason for hiding this comment

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

The semantics aren't quite sitting well with me. But let's merge this and address any concerns later.

return new RemoteConfigParameter()
.setDefaultValue(defaultValue.toRemoteConfigParameterValue())
.setDefaultValue(remoteConfigParameterValue)
.setDescription(description).setConditionalValues(conditionalPublicValues);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: One setter per line

public ParameterResponse(@Nullable ParameterValueResponse defaultValue,
@Nullable String description,
@NonNull Map<String, ParameterValueResponse> conditionalValues) {
checkNotNull(conditionalValues, "conditional values must not be null.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably redundant at this level.

@lahirumaramba lahirumaramba merged commit 150b121 into remote-config Oct 2, 2020
@lahirumaramba lahirumaramba deleted the lm-rc-parameters branch October 2, 2020 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants