Repository navigation
Conversation
… Storage request without swallowing cancellation
… in tests, and keep FirebaseAppTest data in its temporary folder
…rebase initializes with it
…failures on every OS
…, and terminate Firestore after its test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the bundled Remote Config (21.6.0) and Installations (17.2.0) libraries work on the JVM. Like the other products, it runs the unmodified Android code and fills in the Android shims it needs.
What works
setDefaultsAsync(Map),fetch,activate,fetchAndActivate,get*/getValue,getAll,getKeysByPrefix,getInfo,setConfigSettingsAsync, andreset.FirebaseApp.setDataCollectionDefaultEnabled, which previously crashed because the shims had noSharedPreferences.putBooleanorContext.createDeviceProtectedStorageContext.Not supported: realtime updates (
addOnConfigUpdateListener), and defaults loaded from XML resources.Changes
FirebasePlatform.getFilesDir()is a new overridable method. It defaults to<tmpdir>/firebase-files, andContext.filesDir,openFileInput,openFileOutput, anddeleteFileuse it. File names are URL-encoded, because Remote Config puts the app ID (which contains:) in its file names.SharedPreferencesare stored as files, the way Android stores them. Each preferences file is one JSON file atgetFilesDir()/shared_prefs/<name>.json, handled by the newPreferencesFile: values keep their types, edits are batched untilcommit()/apply()as on Android, and each commit syncs a temporary file to disk and moves it over the old one atomically. As on Android, memory is updated even if the disk write fails, and a later commit writes the values again. This replaces the strict whitelist inContext.getSharedPreferences, which threw on unknown keys. Keeping preferences next to Remote Config's config files means the two can't drift apart when only one of them is persisted. The shim interface gainsgetInt,getBoolean,getStringSet,putInt,putBoolean,putStringSet,remove, andclear, andgetAll()now has Android'sMap<String, ?>signature.android.util.JsonReader(withJsonToken,JsonScope,MalformedJsonException, andcom.android.internal.util.StringPool), plusBase64DataException. The existingBase64OutputStreamshim already referencedBase64DataExceptionbut nobody had ported it.TrafficStats(no-op),DateUtils.formatElapsedTime,Configuration.locale, andResources.getConfiguration().RemoteConfigRegistrarandAbtRegistrarare registered in thePackageManagershim. Remote Config starts with the default app and casts its context toApplication, soContext.applicationContextnow returns anApplicationfor a plainContext, andFirebase.initialize(Context(), options)keeps working.getFilesDir. It also states thatFirebasePlatform's key-value storage must be thread-safe, because Auth writes to it from network threads, and the example now uses aConcurrentHashMap.Note for
FirebasePlatformimplementersOnly Auth uses
store/retrieve/clear, as before; Firebase-internal preferences don't reach them. The defaultgetFilesDir()is in the OS temp folder, likegetDatabasePath(). OS cleaners can delete Remote Config's config files while its preferences remain, which leaves it serving default values until the template changes. The README therefore recommends that production apps overridegetFilesDir()with a persistent folder.Tests
FirebaseRemoteConfigTestports the Remote Config tests from firebase-kotlin-sdk'sfirebase-configcommon tests one-to-one onto the Android API. The two fetch tests that need a publishedtest_remote_stringparameter keep their@Ignore, as they have upstream. A livefetchAndActivate succeedstest runs against thefir-java-sdkproject. The expected JVM warnings (no package info to fingerprint, no Analytics SDK for A/B testing) are captured and asserted, and any other log fails the test.Contextfile APIs,PreferencesFile(types, isolation between files, batched edits, reading back a written file, concurrent commits, corrupt files, and failed and retried writes),JsonReader, andDateUtils.HeartBeatTestregisters a heartbeat and checks that it reached the file on disk.FirebaseAppTestcovers initializing with a plainContextand changing the data collection default.FirebaseTestgets its own folder for files and databases underbuild/test-data, kept until the next run, so Firebase's background work can't leak into later tests.FirebaseFirestoreTestterminates Firestore after its test, and the test stores are thread-safe. Tests that capture logs fail on any line they don't expect.firebase emulators:exec ... './gradlew cleanTest build': 59 tests, 57 pass and 2 are ignored, and ktlint is clean.Known limitations
File.renameTo). On Windows that rename fails when the target exists. The library swallows theIOException, so the installation would probably register again on every token fetch, and temp files would accumulate ingetFilesDir(). I confirmed this from the bytecode and JDK behaviour; I have not tested it on Windows. The shims can't intercept the rename.getFilesDir()there is/tmp/firebase-files, shared by every OS user, so other local users can read the installation data and Remote Config files in it. Apps on shared machines should overridegetFilesDir(), as the README already recommends for production apps.getDatabasePath()'s default has the same exposure and predates this change.