-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
feat(remote-config): Expose modular API that matches the Firebase web JS SDK v9 API #6868
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
Codecov Report
@@ Coverage Diff @@
## main #6868 +/- ##
============================================
- Coverage 54.46% 54.38% -0.07%
- Complexity 718 720 +2
============================================
Files 225 226 +1
Lines 11102 11177 +75
Branches 1749 1764 +15
============================================
+ Hits 6046 6078 +32
- Misses 4724 4768 +44
+ Partials 332 331 -1 |
interesting - on the 3 questions listed currently in description - 1- to be firebase-js-sdk compatible we need to define the LogLevel type as well https://firebase.google.com/docs/reference/js/remote-config.md#loglevel and support the setLogLevel API, I think 'error' is probably the better choice for default return value as it will imply on native that you are not going to get any special non-error logging, and have a note that just says "setter is ignored on native" 2- we have to have a setter to be compatible, so it should do delegate to the existing implementation and just not await on it I guess. javascript property setters can delegate to other methods right? It's just the other direction (non-property implementations delegating to property setters) that doesn't work, as you learned+mentioned the other day? 3- same here we have to have the setter to be compatible. I just read an issue logged against the TC39 committee plus some stackoverflow and there is not and probably will never by async setters which - to me - just argues for never using javascript properties but firebase-js-sdk forces us to. So both 2 and 3 - implement the setter so we are compatible, perhaps with a note that it is async on native platforms, and people should await on the native API or await on a short sleep if avoiding a race condition is critical 🤷 |
@mikehardy I've updated the PR to delegate the setters to the existing async API. The difference between perf and remote-config is; it didn't matter that we didn't have to await dataCollectionEnabled setter on perf because it would only take effect on the next app run, and we updated a simple boolean on the perf instance before getting to native. The two setters for remote-config update the settings and default config on the remote-config instance after sending them to native. I guess we should update them before they get to native? 🤔 |
Updating the local instance before going to native seems best so that at least after the property setting returns it has an expected value if re-tested, even though native will be potentially still working async. This is a platform inconsistency we can't really bridge but I think a note in the docs "due to the nature of the react-native javascript/native bridge the actual native effect is asynchronous and there may be a slight delay at the native level before this takes effect. If that's important to your app, and you want to use the firebase-js-sdk compatible property setters, insert a small sleep after calling the setters" or similar ? |
We have a bit of an issue with web. The current, native See here. I've drafted this commit to get your thoughts, @mikehardy? Will update tests and make note about non-async stuff for the setter but thought I'd see what you think of this first? |
@russellwheatley I think the native interfaces do not matter much, the only really important thing is that the JS (and Typescript) API is firebase-js-sdk compatible, and it appears we took some care to do that - firebase-js-sdk API is in millis and our API is in millis so we don't have a breaking change on tap here. No problem if our internal JS code is translating between millis and seconds (which it is doing now), we can just keep right on doing that. And same with the property names - as long as we present a firebase-js-sdk compatible facade at the JS layer, native can be whatever it needs to be Stated more practically: I think this may actually be close then - allowing for the "dangit, react-native is async..." stuff as a slight difference, which I think you've handled reasonably given constraints that javascript properties can't be async but react-native has to be over the bridge |
@mikehardy, I changed the API for a couple of reasons. I wanted to make them cross platform and follow DRY principles. The way to now think about This is the same for
I have been a bit sneaky with the error messages so they correctly output the correct API call. I do this by using call method to pass another argument that isn't part of the API. Retrieve it here for correct error message. I'm sure you know, but simple demonstration of how that works: function func1(a) {
console.log(arguments[0]);
// Expected output: 1
console.log(arguments[1]);
// Expected output: 2
}
func1.call(this, 1, 2) I hope you see this as an improvement? Can change back if it's a little too complicated, and you wanted to keep each API separate and dedicated to their respective platforms 😅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit fancy but not too fancy, and how else to bridge the "property setters can't be async" + "apple/android expect seconds not millis" well? I think this does a good job
/** | ||
* The status of the latest Remote RemoteConfig fetch action. | ||
*/ | ||
type LastFetchStatusType = 'success' | 'failure' | 'no_fetch_yet' | 'throttled'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice - a real type is an improvement
|
||
/** | ||
* Provides an object which provides the properties `minimumFetchIntervalMillis` & `fetchTimeMillis` if they have been set | ||
* using setConfigSettings({ fetchTimeMillis: number, minimumFetchIntervalMillis: number }). A description of the properties | ||
* can be found above | ||
* | ||
*/ | ||
settings: { fetchTimeMillis: number; minimumFetchIntervalMillis: number }; | ||
settings: ConfigSettings; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆 why wasn't it like this before !? nice improvement
throw new Error("firebase.remoteConfig().defaultConfig: 'defaults' must be an object."); | ||
} | ||
// To make Firebase web v9 API compatible, we update the config first so it immediately | ||
// updates defaults on the instance. We then pass to web platform to update. We do this because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a quibble on wording, but it's a mentality - if we work with apple/android/web we are not passing to web just because it's the modular API we present, we're wrapping any of the SDKs, so mental model is "we handle our business in the wrapping layer then hand off to SDK...", not just "web"
// updates defaults on the instance. We then pass to web platform to update. We do this because | |
// updates defaults on the instance. We then pass to underlying SDK to update. We do this because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't perturb the PR with these FWIW but still worth thinking about w.r.t. mental model :-)
|
||
set settings(settings) { | ||
// To make Firebase web v9 API compatible, we update the settings first so it immediately | ||
// updates settings on the instance. We then pass to web platform to update. We do this because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// updates settings on the instance. We then pass to web platform to update. We do this because | |
// updates settings on the instance. We then pass to underlying SDK to update. We do this because |
Description
Feedback welcome on the following:
setLogLevel()
API on web has no counterpart on native. At the moment, it just returnsdebug
. See here.Related issues
Release Summary
Checklist
Android
iOS
e2e
tests added or updated inpackages/\*\*/e2e
jest
tests added or updated inpackages/\*\*/__tests__
Test Plan
Think
react-native-firebase
is great? Please consider supporting the project with any of the below:React Native Firebase
andInvertase
on Twitter