├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── increase-api-coverage.md ├── actions │ └── setup_test_action │ │ └── action.yml ├── dependabot.yml └── workflows │ ├── publish.yml │ ├── pull_request.yml │ └── push.yml ├── .gitignore ├── .idea └── externalDependencies.xml ├── .opensource └── project.json ├── LICENSE ├── README.md ├── build.gradle.kts ├── convention-plugin-test-option ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── EmulatorJobsMatrix.kt │ ├── TestOptionsConfig.kt │ └── testOptionsConvention.gradle.kts ├── documentation ├── gitlive-logo.png ├── homepage.svg └── logo-styles.css ├── firebase-analytics ├── api │ ├── android │ │ └── firebase-analytics.api │ └── jvm │ │ └── firebase-analytics.api ├── build.gradle.kts ├── documentation.md ├── firebase_analytics.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ ├── AnalyticEventConstants.kt │ │ └── analytics.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ ├── analytics.kt │ │ └── externals │ │ └── analytics.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.kt │ ├── jvmMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── analytics │ │ └── analytics.jvm.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── analytics │ └── analytics.kt ├── firebase-app ├── api │ ├── android │ │ └── firebase-app.api │ └── jvm │ │ └── firebase-app.api ├── build.gradle.kts ├── documentation.md ├── firebase_app.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ ├── externals │ │ └── app.kt │ │ └── firebase.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firebase.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── firebase.kt ├── firebase-auth ├── api │ ├── android │ │ └── firebase-auth.api │ └── jvm │ │ └── firebase-auth.api ├── build.gradle.kts ├── documentation.md ├── firebase_auth.podspec ├── karma.config.d │ └── karma.conf.js ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ └── auth.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ ├── auth.kt │ │ ├── credentials.kt │ │ ├── multifactor.kt │ │ └── user.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ └── auth.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ ├── auth.kt │ │ ├── credentials.kt │ │ ├── multifactor.kt │ │ └── user.kt │ ├── commonTest │ ├── kotlin │ │ └── dev │ │ │ └── gitlive │ │ │ └── firebase │ │ │ └── auth │ │ │ └── auth.kt │ └── resources │ │ └── entitlements.plist │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ ├── auth.kt │ │ ├── credentials.kt │ │ ├── multifactor.kt │ │ └── user.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ └── auth.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ ├── auth.kt │ │ ├── credentials.kt │ │ ├── externals │ │ └── auth.kt │ │ ├── multifactor.kt │ │ └── user.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ └── auth.kt │ ├── jvmMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── auth │ │ ├── auth.kt │ │ ├── credentials.kt │ │ ├── multifactor.kt │ │ └── user.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── auth │ └── auth.kt ├── firebase-common-internal ├── api │ ├── android │ │ └── firebase-common-internal.api │ └── jvm │ │ └── firebase-common-internal.api ├── build.gradle.kts ├── package.json └── src │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── internal │ │ ├── EncodedObject.kt │ │ ├── _decoders.kt │ │ └── _encoders.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── internal │ │ ├── EncodeDecodeSettings.kt │ │ ├── EncodedObject.kt │ │ ├── Polymorphic.kt │ │ ├── decoders.kt │ │ ├── encoders.kt │ │ ├── reencodeTransformation.kt │ │ └── serializers.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── internal │ │ └── EncodersTest.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── internal │ │ ├── EncodedObject.kt │ │ ├── _decoders.kt │ │ └── _encoders.kt │ └── jsMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── internal │ ├── EncodedObject.kt │ ├── _decoders.kt │ └── _encoders.kt ├── firebase-common ├── api │ ├── android │ │ └── firebase-common.api │ └── jvm │ │ └── firebase-common.api ├── build.gradle.kts ├── package.json └── src │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ ├── EncodeDecodeSettings.kt │ │ └── FirebaseClassDiscriminator.kt │ └── jsMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── Unsubscribe.kt ├── firebase-config ├── api │ ├── android │ │ └── firebase-config.api │ └── jvm │ │ └── firebase-config.api ├── build.gradle.kts ├── documentation.md ├── firebase_config.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ └── RemoteConfig.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ ├── FirebaseRemoteConfig.kt │ │ └── FirebaseRemoteConfigValue.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ └── RemoteConfig.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ ├── FirebaseRemoteConfig.kt │ │ ├── FirebaseRemoteConfigInfo.kt │ │ ├── FirebaseRemoteConfigSettings.kt │ │ └── FirebaseRemoteConfigValue.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ └── FirebaseRemoteConfig.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ ├── FirebaseRemoteConfig.kt │ │ ├── FirebaseRemoteConfigValue.kt │ │ └── NSDataExtension.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ ├── NSDataExtensionTest.kt │ │ └── RemoteConfig.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ ├── FirebaseRemoteConfig.kt │ │ ├── FirebaseRemoteConfigValue.kt │ │ └── externals │ │ └── remoteconfig.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── remoteconfig │ │ └── FirebaseRemoteConfig.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── remoteconfig │ └── RemoteConfig.kt ├── firebase-crashlytics ├── api │ └── firebase-crashlytics.api ├── build.gradle.kts ├── documentation.md ├── firebase_crashlytics.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── dev │ │ │ └── gitlive │ │ │ └── firebase │ │ │ └── crashlytics │ │ │ └── crashlytics.kt │ └── res │ │ └── values │ │ └── strings.xml │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── crashlytics │ │ └── crashlytics.kt │ └── jvmMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── crashlytics │ └── crashlytics.jvm.kt ├── firebase-database ├── api │ ├── android │ │ └── firebase-database.api │ └── jvm │ │ └── firebase-database.api ├── build.gradle.kts ├── documentation.md ├── firebase_database.podspec ├── karma.config.d │ └── karma.conf.js ├── package.json └── src │ ├── androidInstrumentedTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ └── database.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ ├── ServerValue.kt │ │ └── database.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ └── database.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ ├── ServerValue.kt │ │ └── database.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ └── database.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ ├── ServerValue.kt │ │ └── database.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ └── database.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ ├── ServerValue.kt │ │ ├── database.kt │ │ └── externals │ │ ├── callbacks.kt │ │ └── database.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── database │ │ └── database.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── database │ └── database.kt ├── firebase-firestore ├── api │ ├── android │ │ └── firebase-firestore.api │ └── jvm │ │ └── firebase-firestore.api ├── build.gradle.kts ├── documentation.md ├── firebase_firestore.podspec ├── karma.config.d │ └── karma.conf.js ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── Ignore.kt │ │ └── firestore.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── FieldValue.kt │ │ ├── GeoPoint.kt │ │ ├── Timestamp.kt │ │ ├── _encoders.kt │ │ ├── firestore.kt │ │ └── internal │ │ ├── NativeCollectionReferenceWrapper.kt │ │ ├── NativeDocumentReference.kt │ │ ├── NativeDocumentSnapshotWrapper.kt │ │ ├── NativeFirebaseFirestoreWrapper.kt │ │ ├── NativeQueryWrapper.kt │ │ ├── NativeTransactionWrapper.kt │ │ ├── NativeWriteBatchWrapper.kt │ │ ├── SetOptions.kt │ │ ├── Source.kt │ │ └── callbackExecutorMap.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── Ignore.kt │ │ └── firestore.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── DocumentReferenceSerializer.kt │ │ ├── FieldValue.kt │ │ ├── FieldValueSerializer.kt │ │ ├── Filter.kt │ │ ├── GeoPoint.kt │ │ ├── GeoPointSerializer.kt │ │ ├── LocalCacheSettings.kt │ │ ├── Timestamp.kt │ │ ├── TimestampSerializer.kt │ │ ├── encoders.kt │ │ ├── firestore.kt │ │ ├── helpers.kt │ │ └── internal │ │ ├── NativeCollectionReferenceWrapper.kt │ │ ├── NativeDocumentReference.kt │ │ ├── NativeDocumentSnapshotWrapper.kt │ │ ├── NativeFirebaseFirestoreWrapper.kt │ │ ├── NativeQueryWrapper.kt │ │ ├── NativeTransactionWrapper.kt │ │ ├── NativeWriteBatchWrapper.kt │ │ ├── SafeValue.kt │ │ └── SetOptions.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── FieldValueTests.kt │ │ ├── FirestoreSourceTest.kt │ │ ├── GeoPointTests.kt │ │ ├── Ignore.kt │ │ ├── TimestampTests.kt │ │ └── firestore.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── FieldValue.kt │ │ ├── GeoPoint.kt │ │ ├── Timestamp.kt │ │ ├── _encoders.kt │ │ ├── firestore.kt │ │ └── internal │ │ ├── NativeCollectionReferenceWrapper.kt │ │ ├── NativeDocumentReference.kt │ │ ├── NativeDocumentSnapshotWrapper.kt │ │ ├── NativeFirebaseFirestoreWrapper.kt │ │ ├── NativeQueryWrapper.kt │ │ ├── NativeTransactionWrapper.kt │ │ ├── NativeWriteBatchWrapper.kt │ │ ├── Source.kt │ │ └── throwError.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── ContextSwitchTest.kt │ │ ├── Ignore.kt │ │ └── firestore.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── FieldValue.kt │ │ ├── GeoPoint.kt │ │ ├── Timestamp.kt │ │ ├── _encoders.kt │ │ ├── externals │ │ └── firestore.kt │ │ ├── firestore.kt │ │ └── internal │ │ ├── NativeCollectionReferenceWrapper.kt │ │ ├── NativeDocumentReference.kt │ │ ├── NativeDocumentSnapshotWrapper.kt │ │ ├── NativeFirebaseFirestoreWrapper.kt │ │ ├── NativeQueryWrapper.kt │ │ ├── NativeTransactionWrapper.kt │ │ ├── NativeWriteBatchWrapper.kt │ │ └── SetOptions.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── firestore │ │ ├── Ignore.kt │ │ └── firestore.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── firestore │ ├── Ignore.kt │ └── firestore.kt ├── firebase-functions ├── api │ ├── android │ │ └── firebase-functions.api │ └── jvm │ │ └── firebase-functions.api ├── build.gradle.kts ├── documentation.md ├── firebase_functions.podspec ├── package.json └── src │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── functions │ │ └── functions.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── functions │ │ └── functions.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── functions │ │ └── functions.kt │ └── jsMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── functions │ ├── externals │ ├── HttpsCallableExt.kt │ └── functions.kt │ └── functions.kt ├── firebase-installations ├── api │ ├── android │ │ └── firebase-installations.api │ └── jvm │ │ └── firebase-installations.api ├── build.gradle.kts ├── documentation.md ├── firebase_installations.podspec ├── package.json └── src │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── installations │ │ └── installations.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── installations │ │ └── installations.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── installations │ │ └── installations.kt │ └── jsMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── installations │ ├── externals │ └── installations.kt │ └── installations.kt ├── firebase-messaging ├── api │ ├── android │ │ └── firebase-messaging.api │ └── jvm │ │ └── firebase-messaging.api ├── build.gradle.kts ├── documentation.md ├── firebase_messaging.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ └── messaging.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── messaging │ │ ├── externals │ │ └── messaging.kt │ │ └── messaging.kt │ └── jvmMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── messaging │ └── messaging.kt ├── firebase-perf ├── api │ ├── android │ │ └── firebase-perf.api │ └── jvm │ │ └── firebase-perf.api ├── build.gradle.kts ├── documentation.md ├── firebase_perf.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ ├── performance.kt │ │ └── session │ │ └── PerfSession.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ └── performance.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ └── performance.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── externals │ │ └── performance.kt │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.kt │ │ └── performance.kt │ ├── jvmMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── perf │ │ ├── metrics │ │ └── Trace.jvm.kt │ │ └── performance.jvm.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── perf │ └── performance.kt ├── firebase-storage ├── api │ ├── android │ │ └── firebase-storage.api │ └── jvm │ │ └── firebase-storage.api ├── build.gradle.kts ├── documentation.md ├── firebase_storage.podspec ├── package.json └── src │ ├── androidInstrumentedTest │ ├── AndroidManifest.xml │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ ├── storage.android.kt │ │ └── storage.kt │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ └── storage.kt │ ├── androidUnitTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ ├── storage.android.kt │ │ └── storage.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ └── storage.kt │ ├── commonTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ └── storage.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ └── storage.kt │ ├── iosTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ ├── storage.ios.kt │ │ └── storage.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ ├── externals │ │ └── storage.kt │ │ └── storage.kt │ ├── jsTest │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ ├── storage.js.kt │ │ └── storage.kt │ ├── jvmMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── storage │ │ └── storage.jvm.kt │ └── jvmTest │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── storage │ ├── storage.jvm.kt │ └── storage.kt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts ├── test-utils ├── api │ ├── android │ │ └── test-utils.api │ └── jvm │ │ └── test-utils.api ├── build.gradle.kts └── src │ ├── androidMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── TestUtils.kt │ ├── commonMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── TestUtils.kt │ ├── iosMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── TestUtils.kt │ ├── jsMain │ └── kotlin │ │ └── dev │ │ └── gitlive │ │ └── firebase │ │ └── TestUtils.kt │ └── jvmMain │ └── kotlin │ └── dev │ └── gitlive │ └── firebase │ └── TestUtils.kt └── test ├── .firebaserc ├── database.rules.json ├── firebase.json ├── firestore.rules └── storage.rules /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{kt,kts}] 4 | ktlint_code_style = intellij_idea 5 | ktlint_ignore_back_ticked_identifier = true 6 | 7 | ktlint_standard = enabled 8 | ktlint_standard_no-wildcard-imports = disabled 9 | ktlint_standard_filename = disabled 10 | ktlint_standard_import-ordering = disabled 11 | ktlint_standard_function-naming = disabled 12 | 13 | ktlint_experimental = disabled 14 | 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [GitLiveApp] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/increase-api-coverage.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Increase API Coverage 3 | about: Request for implementation of missing APIs 4 | title: Add [class name].[function name] to [library name] for [platform names] 5 | labels: API coverage 6 | assignees: '' 7 | 8 | --- 9 | 10 | | Library | Class | Member | Platforms | 11 | |:---------|:-----------------|:---------------------|:-----------------| 12 | | e.g auth | e.g FirebaseAuth | e.g signInWithGithub | e.g Android, iOS | 13 | -------------------------------------------------------------------------------- /.github/actions/setup_test_action/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup Tests' 2 | description: 'Prepares to run tests on Firebase emulator' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Set up JDK 8 | uses: actions/setup-java@v4 9 | with: 10 | distribution: 'zulu' 11 | java-version: '17' 12 | cache: gradle 13 | - name: Set up Node.js 14 | uses: actions/setup-node@v4 15 | with: 16 | node-version: '21.x' 17 | - name: Upgrade packages 18 | shell: bash 19 | run: npm update 20 | - name: Gradle cache 21 | uses: gradle/actions/setup-gradle@v4 22 | - name: Grant execute permission for gradlew 23 | shell: bash 24 | run: chmod +x gradlew 25 | - name: Install Firebase tools 26 | shell: bash 27 | run: npm install -g firebase-tools wait-on 28 | - name: Start Firebase emulator 29 | shell: bash 30 | run: | 31 | firebase emulators:start --config=./test/firebase.json & 32 | wait-on http://127.0.0.1:9099 33 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gradle" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | name: Push 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | formatKotlin: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | contents: write 10 | steps: 11 | - uses: actions/checkout@v4 12 | with: 13 | ref: ${{ github.head_ref }} 14 | - name: Set up JDK 15 | uses: actions/setup-java@v4 16 | with: 17 | distribution: 'zulu' 18 | java-version: '17' 19 | - name: formatKotlin 20 | run: ./gradlew formatKotlin 21 | - uses: stefanzweifel/git-auto-commit-action@v5 22 | - name: lintKotlin 23 | run: ./gradlew lintKotlin 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /**/.gradle/ 3 | /**/build/ 4 | /.idea/ 5 | local.properties 6 | /**/*.iml 7 | *.iml 8 | Firebase*.zip 9 | /Firebase 10 | .DS_Store 11 | *.log 12 | /kotlin-js-store/ 13 | /kotlin-js-store/yarn.lock 14 | 15 | .kotlin/ 16 | -------------------------------------------------------------------------------- /.idea/externalDependencies.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.opensource/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Firebase Kotlin SDK (unofficial)", 3 | "platforms": [ 4 | "Android", 5 | "iOS", 6 | "Web" 7 | ], 8 | "content": "README.md", 9 | "related": [ 10 | "firebase/firebase-android-sdk", 11 | "firebase/firebase-ios-sdk", 12 | "firebase/firebase-js-sdk" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /convention-plugin-test-option/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | } 4 | 5 | dependencies { 6 | compileOnly(libs.android.gradle.plugin) 7 | compileOnly(libs.gson) 8 | } 9 | -------------------------------------------------------------------------------- /convention-plugin-test-option/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | versionCatalogs { 7 | create("libs") { 8 | from(files("../gradle/libs.versions.toml")) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /convention-plugin-test-option/src/main/kotlin/TestOptionsConfig.kt: -------------------------------------------------------------------------------- 1 | import com.android.build.api.dsl.ManagedVirtualDevice 2 | import com.android.build.api.dsl.TestOptions 3 | import org.gradle.api.Project 4 | import org.gradle.kotlin.dsl.create 5 | import org.gradle.kotlin.dsl.provideDelegate 6 | 7 | fun TestOptions.configureTestOptions(project: Project) { 8 | val targetSdkVersion: Int by project 9 | targetSdk = targetSdkVersion 10 | unitTests { 11 | isIncludeAndroidResources = true 12 | all { test: org.gradle.api.tasks.testing.Test -> 13 | test.testLogging { 14 | exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL 15 | events = setOf( 16 | org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED, 17 | org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED, 18 | org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED, 19 | org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_OUT, 20 | org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_ERROR, 21 | org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED 22 | ) 23 | } 24 | } 25 | } 26 | animationsDisabled = true 27 | emulatorSnapshots { 28 | enableForTestFailures = false 29 | } 30 | managedDevices.devices.create("gradleManagedDevice") { 31 | device = "Pixel 2" 32 | apiLevel = 33 33 | systemImageSource = "google-atd" 34 | require64Bit = true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /convention-plugin-test-option/src/main/kotlin/testOptionsConvention.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | } 3 | -------------------------------------------------------------------------------- /documentation/gitlive-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GitLiveApp/firebase-kotlin-sdk/eafd4f4dc2a54d46bf9deafcb430387701889aab/documentation/gitlive-logo.png -------------------------------------------------------------------------------- /documentation/homepage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /documentation/logo-styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --dokka-logo-image-url: url('../images/gitlive-logo.png'); 3 | --dokka-logo-height: 50px; 4 | --dokka-logo-width: 50px; 5 | } -------------------------------------------------------------------------------- /firebase-analytics/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-analytics 2 | This module is a direct forward of the Firebase Analytics library. It provides the main functionality, like logging events. -------------------------------------------------------------------------------- /firebase-analytics/firebase_analytics.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_analytics' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_analytics.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-analytics', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_analytics', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_analytics', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-analytics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-analytics", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-analytics.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.6.10", 29 | "kotlinx-coroutines-core": "1.6.1-native-mt" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-analytics/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-analytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.analytics 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-analytics/src/androidUnitTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.analytics 2 | 3 | import org.junit.Ignore 4 | 5 | actual val context: Any = "" 6 | 7 | actual typealias IgnoreForAndroidUnitTest = Ignore 8 | -------------------------------------------------------------------------------- /firebase-analytics/src/commonTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.analytics 6 | 7 | import dev.gitlive.firebase.Firebase 8 | import dev.gitlive.firebase.FirebaseOptions 9 | import dev.gitlive.firebase.apps 10 | import dev.gitlive.firebase.initialize 11 | import dev.gitlive.firebase.runBlockingTest 12 | import kotlin.test.AfterTest 13 | import kotlin.test.BeforeTest 14 | import kotlin.test.Test 15 | import kotlin.test.assertNotNull 16 | 17 | expect val context: Any 18 | expect annotation class IgnoreForAndroidUnitTest() 19 | 20 | @IgnoreForAndroidUnitTest 21 | class FirebaseAnalyticsTest { 22 | 23 | lateinit var analytics: FirebaseAnalytics 24 | 25 | @BeforeTest 26 | fun initializeFirebase() { 27 | val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize( 28 | context, 29 | FirebaseOptions( 30 | applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a", 31 | apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0", 32 | databaseUrl = "https://fir-kotlin-sdk.firebaseio.com", 33 | storageBucket = "fir-kotlin-sdk.appspot.com", 34 | projectId = "fir-kotlin-sdk", 35 | gcmSenderId = "846484016111", 36 | ), 37 | ) 38 | 39 | analytics = Firebase.analytics(app) 40 | } 41 | 42 | @AfterTest 43 | fun deinitializeFirebase() = runBlockingTest { 44 | Firebase.apps(context).forEach { 45 | it.delete() 46 | } 47 | } 48 | 49 | @Test 50 | fun testAnalyticsShouldNotCrash() { 51 | assertNotNull(analytics) 52 | 53 | // This should not crash, otherwise the test will fail 54 | analytics.logEvent("test") { 55 | param("key", "value") 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /firebase-analytics/src/iosTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.analytics 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-analytics/src/jsMain/kotlin/dev/gitlive/firebase/analytics/externals/analytics.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("ktlint:standard:property-naming", "PropertyName") 2 | @file:JsModule("firebase/analytics") 3 | @file:JsNonModule 4 | 5 | package dev.gitlive.firebase.analytics.externals 6 | 7 | import dev.gitlive.firebase.externals.FirebaseApp 8 | import kotlin.js.Promise 9 | 10 | public external fun getAnalytics(app: FirebaseApp? = definedExternally): FirebaseAnalytics 11 | 12 | public external fun logEvent(app: FirebaseAnalytics, name: String, parameters: Map?) 13 | public external fun setUserProperty(app: FirebaseAnalytics, name: String, value: String) 14 | public external fun setUserId(app: FirebaseAnalytics, id: String?) 15 | public external fun resetAnalyticsData(app: FirebaseAnalytics) 16 | public external fun setDefaultEventParameters(app: FirebaseAnalytics, parameters: Map) 17 | public external fun setAnalyticsCollectionEnabled(app: FirebaseAnalytics, enabled: Boolean) 18 | public external fun setSessionTimeoutInterval(app: FirebaseAnalytics, sessionTimeoutInterval: Long) 19 | public external fun getSessionId(app: FirebaseAnalytics): Promise 20 | public external fun setConsent(app: FirebaseAnalytics, consentSettings: ConsentSettings) 21 | 22 | public external interface FirebaseAnalytics 23 | 24 | public external class ConsentSettings { 25 | public var ad_personalization: String? 26 | public var ad_storage: String? 27 | public var ad_user_data: String? 28 | public var analytics_storage: String? 29 | public var functionality_storage: String? 30 | public var personalization_storage: String? 31 | public var security_storage: String? 32 | } 33 | -------------------------------------------------------------------------------- /firebase-analytics/src/jsTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.analytics 2 | 3 | actual val context: Any = Unit 4 | 5 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 6 | actual annotation class IgnoreForAndroidUnitTest 7 | -------------------------------------------------------------------------------- /firebase-analytics/src/jvmMain/kotlin/dev/gitlive/firebase/analytics/analytics.jvm.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.analytics 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.FirebaseException 6 | import kotlin.time.Duration 7 | 8 | public actual val Firebase.analytics: FirebaseAnalytics 9 | get() = TODO("Not yet implemented") 10 | 11 | public actual fun Firebase.analytics(app: FirebaseApp): FirebaseAnalytics { 12 | TODO("Not yet implemented") 13 | } 14 | 15 | public actual class FirebaseAnalytics { 16 | public actual fun setUserProperty(name: String, value: String) {} 17 | public actual fun setUserId(id: String?) {} 18 | public actual fun resetAnalyticsData() {} 19 | public actual fun setAnalyticsCollectionEnabled(enabled: Boolean) {} 20 | public actual fun setSessionTimeoutInterval(sessionTimeoutInterval: Duration) {} 21 | public actual suspend fun getSessionId(): Long? = TODO("Not yet implemented") 22 | public actual fun setDefaultEventParameters(parameters: Map) {} 23 | public actual fun logEvent(name: String, parameters: Map?) {} 24 | 25 | public actual fun setConsent(consentSettings: Map) {} 26 | 27 | public actual enum class ConsentType { 28 | AD_PERSONALIZATION, 29 | AD_STORAGE, 30 | AD_USER_DATA, 31 | ANALYTICS_STORAGE, 32 | } 33 | 34 | public actual enum class ConsentStatus { 35 | GRANTED, 36 | DENIED, 37 | } 38 | } 39 | 40 | public actual class FirebaseAnalyticsException internal constructor(message: String) : FirebaseException(message) 41 | -------------------------------------------------------------------------------- /firebase-analytics/src/jvmTest/kotlin/dev/gitlive/firebase/analytics/analytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.analytics 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val context: Any = testContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-app/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-app 2 | This module is a direct forward of the Firebase App library. It provides the default FirebaseApp instances. -------------------------------------------------------------------------------- /firebase-app/firebase_app.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_app' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_app.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-app', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_app', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_app', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end -------------------------------------------------------------------------------- /firebase-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-app", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-common": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-app/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-app/src/androidUnitTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase 8 | 9 | import org.junit.Ignore 10 | 11 | actual val context: Any = "" 12 | 13 | actual typealias IgnoreForAndroidUnitTest = Ignore 14 | -------------------------------------------------------------------------------- /firebase-app/src/commonTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase 2 | 3 | import kotlin.test.Test 4 | import kotlin.test.assertEquals 5 | 6 | expect val context: Any 7 | expect annotation class IgnoreForAndroidUnitTest() 8 | 9 | @IgnoreForAndroidUnitTest 10 | class FirebaseAppTest { 11 | @Test 12 | fun testInitialize() = runTest { 13 | Firebase.initialize( 14 | context, 15 | FirebaseOptions( 16 | applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a", 17 | apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0", 18 | databaseUrl = "https://fir-kotlin-sdk.firebaseio.com", 19 | storageBucket = "fir-kotlin-sdk.appspot.com", 20 | projectId = "fir-kotlin-sdk", 21 | gcmSenderId = "846484016111", 22 | ), 23 | ) 24 | 25 | assertEquals(1, Firebase.apps(context).size) 26 | 27 | Firebase.apps(context).forEach { 28 | it.delete() 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-app/src/iosTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-app/src/jsMain/kotlin/dev/gitlive/firebase/externals/app.kt: -------------------------------------------------------------------------------- 1 | @file:JsModule("firebase/app") 2 | @file:JsNonModule 3 | 4 | package dev.gitlive.firebase.externals 5 | 6 | import kotlin.js.Promise 7 | 8 | public external fun initializeApp(options: Any, name: String = definedExternally): FirebaseApp 9 | 10 | public external fun getApp(name: String = definedExternally): FirebaseApp 11 | 12 | public external fun getApps(): Array 13 | 14 | public external fun deleteApp(app: FirebaseApp): Promise 15 | 16 | public external interface FirebaseApp { 17 | public val automaticDataCollectionEnabled: Boolean 18 | public val name: String 19 | public val options: FirebaseOptions 20 | } 21 | 22 | public external interface FirebaseOptions { 23 | public val apiKey: String 24 | public val appId: String 25 | public val authDomain: String? 26 | public val databaseURL: String? 27 | public val measurementId: String? 28 | public val messagingSenderId: String? 29 | public val gaTrackingId: String? 30 | public val projectId: String? 31 | public val storageBucket: String? 32 | } 33 | -------------------------------------------------------------------------------- /firebase-app/src/jsTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-app/src/jvmTest/kotlin/dev/gitlive/firebase/firebase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase 8 | 9 | actual val context: Any = testContext 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | -------------------------------------------------------------------------------- /firebase-auth/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-auth 2 | This module is a direct forward of the Firebase Authentication library. It provides the main functionality, like authenticating with Google or Apple. -------------------------------------------------------------------------------- /firebase-auth/firebase_auth.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_auth' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_auth.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-auth', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_auth', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_auth', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end -------------------------------------------------------------------------------- /firebase-auth/karma.config.d/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Some tests are fluky in GitHub Actions, so we increase the timeout. 2 | config.set({ 3 | client: { 4 | mocha: { 5 | timeout: 180000 6 | } 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /firebase-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-auth", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-auth.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-auth/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-auth/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/auth/auth.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.auth 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 14 | 15 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 16 | actual annotation class IgnoreForAndroidUnitTest 17 | -------------------------------------------------------------------------------- /firebase-auth/src/androidUnitTest/kotlin/dev/gitlive/firebase/auth/auth.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.auth 8 | 9 | import org.junit.Ignore 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = "" 14 | 15 | actual typealias IgnoreForAndroidUnitTest = Ignore 16 | -------------------------------------------------------------------------------- /firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/credentials.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.auth 6 | 7 | import dev.gitlive.firebase.Firebase 8 | 9 | public expect open class AuthCredential { 10 | public val providerId: String 11 | } 12 | public expect class PhoneAuthCredential : AuthCredential 13 | 14 | public expect class OAuthCredential : AuthCredential 15 | 16 | public expect object EmailAuthProvider { 17 | public fun credential(email: String, password: String): AuthCredential 18 | public fun credentialWithLink(email: String, emailLink: String): AuthCredential 19 | } 20 | 21 | public expect object FacebookAuthProvider { 22 | public fun credential(accessToken: String): AuthCredential 23 | } 24 | 25 | public expect object GithubAuthProvider { 26 | public fun credential(token: String): AuthCredential 27 | } 28 | 29 | public expect object GoogleAuthProvider { 30 | public fun credential(idToken: String?, accessToken: String?): AuthCredential 31 | } 32 | 33 | public expect class OAuthProvider( 34 | provider: String, 35 | scopes: List = emptyList(), 36 | customParameters: Map = emptyMap(), 37 | auth: FirebaseAuth = Firebase.auth, 38 | ) { 39 | public companion object { 40 | public fun credential(providerId: String, accessToken: String? = null, idToken: String? = null, rawNonce: String? = null): OAuthCredential 41 | } 42 | } 43 | 44 | public expect class PhoneAuthProvider(auth: FirebaseAuth = Firebase.auth) { 45 | public fun credential(verificationId: String, smsCode: String): PhoneAuthCredential 46 | public suspend fun verifyPhoneNumber(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential 47 | } 48 | 49 | public expect interface PhoneVerificationProvider 50 | 51 | public expect object TwitterAuthProvider { 52 | public fun credential(token: String, secret: String): AuthCredential 53 | } 54 | -------------------------------------------------------------------------------- /firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/multifactor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.auth 6 | 7 | public expect class MultiFactor { 8 | public val enrolledFactors: List 9 | public suspend fun enroll(multiFactorAssertion: MultiFactorAssertion, displayName: String?) 10 | public suspend fun getSession(): MultiFactorSession 11 | public suspend fun unenroll(multiFactorInfo: MultiFactorInfo) 12 | public suspend fun unenroll(factorUid: String) 13 | } 14 | 15 | public expect class MultiFactorInfo { 16 | public val displayName: String? 17 | public val enrollmentTime: Double 18 | public val factorId: String 19 | public val uid: String 20 | } 21 | 22 | public expect class MultiFactorAssertion { 23 | public val factorId: String 24 | } 25 | 26 | public expect class MultiFactorSession 27 | 28 | public expect class MultiFactorResolver { 29 | public val auth: FirebaseAuth 30 | public val hints: List 31 | public val session: MultiFactorSession 32 | 33 | public suspend fun resolveSignIn(assertion: MultiFactorAssertion): AuthResult 34 | } 35 | -------------------------------------------------------------------------------- /firebase-auth/src/commonTest/resources/entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | {PERSONAL_ID}.bundle.id 7 | keychain-access-groups 8 | 9 | {PERSONAL_ID}.bundle.id 10 | 11 | 12 | -------------------------------------------------------------------------------- /firebase-auth/src/iosTest/kotlin/dev/gitlive/firebase/auth/auth.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.auth 6 | 7 | actual val emulatorHost: String = "localhost" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | -------------------------------------------------------------------------------- /firebase-auth/src/jsTest/kotlin/dev/gitlive/firebase/auth/auth.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.auth 6 | 7 | actual val emulatorHost: String = "localhost" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | -------------------------------------------------------------------------------- /firebase-auth/src/jvmTest/kotlin/dev/gitlive/firebase/auth/auth.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.auth 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = testContext 14 | 15 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 16 | actual annotation class IgnoreForAndroidUnitTest 17 | -------------------------------------------------------------------------------- /firebase-common-internal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-common-internal", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-common-internal.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-multiplatform-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-multiplatform-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-common": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4", 30 | "kotlinx-serialization-kotlinx-serialization-runtime": "1.3.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/EncodedObject.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("AndroidEncodedObject") 2 | 3 | package dev.gitlive.firebase.internal 4 | 5 | public val EncodedObject.android: Map get() = getRaw() 6 | 7 | @PublishedApi 8 | internal actual fun Any.asNativeMap(): Map<*, *>? = this as? Map<*, *> 9 | -------------------------------------------------------------------------------- /firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.internal 6 | 7 | import kotlinx.serialization.descriptors.PolymorphicKind 8 | import kotlinx.serialization.descriptors.SerialDescriptor 9 | import kotlinx.serialization.descriptors.StructureKind 10 | import kotlin.collections.set 11 | 12 | public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { 13 | StructureKind.LIST -> mutableListOf() 14 | .also { value = it } 15 | .let { FirebaseCompositeEncoder(settings) { _, index, value -> it.add(index, value) } } 16 | StructureKind.MAP -> mutableListOf() 17 | .let { FirebaseCompositeEncoder(settings, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } } 18 | StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor) 19 | is PolymorphicKind -> encodeAsMap(descriptor) 20 | else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") 21 | } 22 | 23 | private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() 24 | .also { value = it } 25 | .let { 26 | FirebaseCompositeEncoder( 27 | settings, 28 | setPolymorphicType = { discriminator, type -> 29 | it[discriminator] = type 30 | }, 31 | set = { _, index, value -> it[descriptor.getElementName(index)] = value }, 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/EncodeDecodeSettings.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.internal 2 | 3 | import dev.gitlive.firebase.DecodeSettings 4 | import dev.gitlive.firebase.EncodeDecodeSettingsBuilder 5 | import dev.gitlive.firebase.EncodeSettings 6 | import kotlinx.serialization.modules.EmptySerializersModule 7 | import kotlinx.serialization.modules.SerializersModule 8 | 9 | @PublishedApi 10 | internal data class EncodeSettingsImpl internal constructor( 11 | override val encodeDefaults: Boolean, 12 | override val serializersModule: SerializersModule, 13 | ) : EncodeSettings { 14 | 15 | @PublishedApi 16 | internal class Builder : EncodeSettings.Builder { 17 | override var encodeDefaults: Boolean = true 18 | override var serializersModule: SerializersModule = EmptySerializersModule() 19 | } 20 | } 21 | 22 | @PublishedApi 23 | internal class DecodeSettingsImpl internal constructor( 24 | override val serializersModule: SerializersModule = EmptySerializersModule(), 25 | ) : DecodeSettings { 26 | 27 | @PublishedApi 28 | internal class Builder : DecodeSettings.Builder { 29 | override var serializersModule: SerializersModule = EmptySerializersModule() 30 | } 31 | } 32 | 33 | @PublishedApi 34 | internal class EncodeDecodeSettingsBuilderImpl : EncodeDecodeSettingsBuilder { 35 | 36 | override var encodeDefaults: Boolean = true 37 | override var serializersModule: SerializersModule = EmptySerializersModule() 38 | } 39 | 40 | @PublishedApi 41 | internal fun EncodeSettings.Builder.buildEncodeSettings(): EncodeSettings = EncodeSettingsImpl(encodeDefaults, serializersModule) 42 | 43 | @PublishedApi 44 | internal fun DecodeSettings.Builder.buildDecodeSettings(): DecodeSettings = DecodeSettingsImpl(serializersModule) 45 | -------------------------------------------------------------------------------- /firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/EncodedObject.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.internal 2 | 3 | import kotlin.jvm.JvmInline 4 | 5 | /** 6 | * Platform specific object for storing encoded data that can be used for methods that explicitly require an object. 7 | * This is essentially a [Map] of [String] and [Any]? (as represented by [raw]) but since [encode] gives a platform specific value, this method wraps that. 8 | */ 9 | public sealed interface EncodedObject 10 | 11 | internal fun EncodedObject.getRaw(): Map = when (this) { 12 | is EncodedObjectImpl -> raw 13 | } 14 | 15 | @JvmInline 16 | @PublishedApi 17 | internal value class EncodedObjectImpl(val raw: Map) : EncodedObject 18 | 19 | @PublishedApi 20 | internal expect fun Any.asNativeMap(): Map<*, *>? 21 | 22 | @PublishedApi 23 | internal fun Map<*, *>.asEncodedObject(): EncodedObject = map { (key, value) -> 24 | if (key is String) { 25 | key to value 26 | } else { 27 | throw IllegalArgumentException("Expected a String key but received $key") 28 | } 29 | }.toMap().let(::EncodedObjectImpl) 30 | -------------------------------------------------------------------------------- /firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/reencodeTransformation.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.internal 2 | 3 | import dev.gitlive.firebase.EncodeDecodeSettingsBuilder 4 | import kotlinx.serialization.KSerializer 5 | 6 | public inline fun reencodeTransformation(value: Any?, builder: EncodeDecodeSettingsBuilder.() -> Unit = {}, transform: (T) -> T): Any? { 7 | val encodeDecodeSettingsBuilder = EncodeDecodeSettingsBuilderImpl().apply(builder) 8 | val oldValue: T = decode(value, encodeDecodeSettingsBuilder.buildDecodeSettings()) 9 | return encode( 10 | transform(oldValue), 11 | encodeDecodeSettingsBuilder.buildEncodeSettings(), 12 | ) 13 | } 14 | 15 | public inline fun reencodeTransformation(strategy: KSerializer, value: Any?, builder: EncodeDecodeSettingsBuilder.() -> Unit = {}, transform: (T) -> T): Any? { 16 | val encodeDecodeSettingsBuilder = EncodeDecodeSettingsBuilderImpl().apply(builder) 17 | val oldValue: T = decode(strategy, value, encodeDecodeSettingsBuilder.buildDecodeSettings()) 18 | return encode( 19 | strategy, 20 | transform(oldValue), 21 | encodeDecodeSettingsBuilder.buildEncodeSettings(), 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/EncodedObject.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.internal 2 | 3 | public val EncodedObject.ios: Map get() = getRaw().mapKeys { (key, _) -> key } 4 | 5 | @PublishedApi 6 | internal actual fun Any.asNativeMap(): Map<*, *>? = this as? Map<*, *> 7 | -------------------------------------------------------------------------------- /firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.internal 6 | 7 | import kotlinx.serialization.descriptors.PolymorphicKind 8 | import kotlinx.serialization.descriptors.SerialDescriptor 9 | import kotlinx.serialization.descriptors.StructureKind 10 | import kotlin.collections.set 11 | 12 | public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { 13 | StructureKind.LIST -> encodeAsList() 14 | StructureKind.MAP -> mutableListOf() 15 | .let { FirebaseCompositeEncoder(settings, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } } 16 | StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor) 17 | is PolymorphicKind -> encodeAsMap(descriptor) 18 | else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") 19 | } 20 | 21 | private fun FirebaseEncoder.encodeAsList(): FirebaseCompositeEncoder = mutableListOf() 22 | .also { value = it } 23 | .let { FirebaseCompositeEncoder(settings) { _, index, value -> it.add(index, value) } } 24 | private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() 25 | .also { value = it } 26 | .let { 27 | FirebaseCompositeEncoder( 28 | settings, 29 | setPolymorphicType = { discriminator, type -> 30 | it[discriminator] = type 31 | }, 32 | set = { _, index, value -> it[descriptor.getElementName(index)] = value }, 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/EncodedObject.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.internal 2 | 3 | import kotlin.js.Json 4 | import kotlin.js.json 5 | 6 | public val EncodedObject.js: Json get() = json(*getRaw().entries.map { (key, value) -> key to value }.toTypedArray()) 7 | 8 | @PublishedApi 9 | internal actual fun Any.asNativeMap(): Map<*, *>? { 10 | val json = when (this) { 11 | is Number -> null 12 | is Boolean -> null 13 | is String -> null 14 | is Map<*, *> -> { 15 | if (keys.all { it is String }) { 16 | json(*mapKeys { (key, _) -> key as String }.toList().toTypedArray()) 17 | } else { 18 | null 19 | } 20 | } 21 | is Collection<*> -> null 22 | is Array<*> -> null 23 | else -> { 24 | @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") 25 | this as Json 26 | } 27 | } ?: return null 28 | val mutableMap = mutableMapOf() 29 | for (key in js("Object").keys(json)) { 30 | mutableMap[key.unsafeCast()] = json[key.unsafeCast()] 31 | } 32 | return mutableMap.toMap() 33 | } 34 | -------------------------------------------------------------------------------- /firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.internal 6 | 7 | import kotlinx.serialization.descriptors.PolymorphicKind 8 | import kotlinx.serialization.descriptors.SerialDescriptor 9 | import kotlinx.serialization.descriptors.StructureKind 10 | import kotlin.js.json 11 | 12 | public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { 13 | StructureKind.LIST -> encodeAsList(descriptor) 14 | StructureKind.MAP -> { 15 | val map = json() 16 | var lastKey = "" 17 | value = map 18 | FirebaseCompositeEncoder(settings) { _, index, value -> 19 | if (index % 2 == 0) { 20 | lastKey = (value as? String) ?: JSON.stringify(value) 21 | } else { 22 | map[lastKey] = value 23 | } 24 | } 25 | } 26 | StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor) 27 | is PolymorphicKind -> encodeAsMap(descriptor) 28 | else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") 29 | } 30 | 31 | private fun FirebaseEncoder.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array(descriptor.elementsCount) { null } 32 | .also { value = it } 33 | .let { FirebaseCompositeEncoder(settings) { _, index, value -> it[index] = value } } 34 | private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = json() 35 | .also { value = it } 36 | .let { 37 | FirebaseCompositeEncoder( 38 | settings, 39 | setPolymorphicType = { discriminator, type -> 40 | it[discriminator] = type 41 | }, 42 | set = { _, index, value -> it[descriptor.getElementName(index)] = value }, 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /firebase-common/api/android/firebase-common.api: -------------------------------------------------------------------------------- 1 | public abstract interface class dev/gitlive/firebase/DecodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { 2 | } 3 | 4 | public abstract interface class dev/gitlive/firebase/DecodeSettings$Builder { 5 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 6 | public abstract fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V 7 | } 8 | 9 | public abstract interface class dev/gitlive/firebase/EncodeDecodeSettings { 10 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 11 | } 12 | 13 | public abstract interface class dev/gitlive/firebase/EncodeDecodeSettingsBuilder : dev/gitlive/firebase/DecodeSettings$Builder, dev/gitlive/firebase/EncodeSettings$Builder { 14 | } 15 | 16 | public abstract interface class dev/gitlive/firebase/EncodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { 17 | public abstract fun getEncodeDefaults ()Z 18 | } 19 | 20 | public abstract interface class dev/gitlive/firebase/EncodeSettings$Builder { 21 | public abstract fun getEncodeDefaults ()Z 22 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 23 | public abstract fun setEncodeDefaults (Z)V 24 | public abstract fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V 25 | } 26 | 27 | public abstract interface annotation class dev/gitlive/firebase/FirebaseClassDiscriminator : java/lang/annotation/Annotation { 28 | public abstract fun discriminator ()Ljava/lang/String; 29 | } 30 | 31 | public synthetic class dev/gitlive/firebase/FirebaseClassDiscriminator$Impl : dev/gitlive/firebase/FirebaseClassDiscriminator { 32 | public fun (Ljava/lang/String;)V 33 | public final synthetic fun discriminator ()Ljava/lang/String; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /firebase-common/api/jvm/firebase-common.api: -------------------------------------------------------------------------------- 1 | public abstract interface class dev/gitlive/firebase/DecodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { 2 | } 3 | 4 | public abstract interface class dev/gitlive/firebase/DecodeSettings$Builder { 5 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 6 | public abstract fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V 7 | } 8 | 9 | public abstract interface class dev/gitlive/firebase/EncodeDecodeSettings { 10 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 11 | } 12 | 13 | public abstract interface class dev/gitlive/firebase/EncodeDecodeSettingsBuilder : dev/gitlive/firebase/DecodeSettings$Builder, dev/gitlive/firebase/EncodeSettings$Builder { 14 | } 15 | 16 | public abstract interface class dev/gitlive/firebase/EncodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { 17 | public abstract fun getEncodeDefaults ()Z 18 | } 19 | 20 | public abstract interface class dev/gitlive/firebase/EncodeSettings$Builder { 21 | public abstract fun getEncodeDefaults ()Z 22 | public abstract fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 23 | public abstract fun setEncodeDefaults (Z)V 24 | public abstract fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V 25 | } 26 | 27 | public abstract interface annotation class dev/gitlive/firebase/FirebaseClassDiscriminator : java/lang/annotation/Annotation { 28 | public abstract fun discriminator ()Ljava/lang/String; 29 | } 30 | 31 | public synthetic class dev/gitlive/firebase/FirebaseClassDiscriminator$Impl : dev/gitlive/firebase/FirebaseClassDiscriminator { 32 | public fun (Ljava/lang/String;)V 33 | public final synthetic fun discriminator ()Ljava/lang/String; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /firebase-common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-common", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-common.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-multiplatform-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-multiplatform-sdk", 25 | "dependencies": { 26 | "firebase": "9.19.1", 27 | "kotlin": "1.8.20", 28 | "kotlinx-coroutines-core": "1.6.4", 29 | "kotlinx-serialization-kotlinx-serialization-runtime": "1.3.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/EncodeDecodeSettings.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase 2 | 3 | import kotlinx.serialization.modules.SerializersModule 4 | 5 | /** 6 | * Settings used to configure encoding/decoding 7 | */ 8 | public sealed interface EncodeDecodeSettings { 9 | 10 | /** 11 | * The [SerializersModule] to use for serialization. This allows for polymorphic serialization on runtime 12 | */ 13 | public val serializersModule: SerializersModule 14 | } 15 | 16 | /** 17 | * [EncodeDecodeSettings] used when encoding an object 18 | * @property encodeDefaults if `true` this will explicitly encode elements even if they are their default value 19 | */ 20 | public interface EncodeSettings : EncodeDecodeSettings { 21 | 22 | public val encodeDefaults: Boolean 23 | 24 | public interface Builder { 25 | public var encodeDefaults: Boolean 26 | public var serializersModule: SerializersModule 27 | } 28 | } 29 | 30 | /** 31 | * [EncodeDecodeSettings] used when decoding an object 32 | * @param serializersModule the [SerializersModule] to use for deserialization. This allows for polymorphic serialization on runtime 33 | */ 34 | public interface DecodeSettings : EncodeDecodeSettings { 35 | 36 | public interface Builder { 37 | public var serializersModule: SerializersModule 38 | } 39 | } 40 | 41 | public interface EncodeDecodeSettingsBuilder : 42 | EncodeSettings.Builder, 43 | DecodeSettings.Builder 44 | -------------------------------------------------------------------------------- /firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseClassDiscriminator.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase 2 | 3 | import kotlinx.serialization.InheritableSerialInfo 4 | 5 | @InheritableSerialInfo 6 | @Target(AnnotationTarget.CLASS) 7 | public annotation class FirebaseClassDiscriminator(val discriminator: String) 8 | -------------------------------------------------------------------------------- /firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/Unsubscribe.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | public typealias Unsubscribe = () -> Unit 8 | -------------------------------------------------------------------------------- /firebase-config/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-config 2 | This module is a direct forward of the Firebase Remote Config library. It provides the main functionality, like remote feature flags. -------------------------------------------------------------------------------- /firebase-config/firebase_config.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_config' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_config.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-config', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_config', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_config', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-config", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-config.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-config/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/remoteconfig/RemoteConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.remoteconfig 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-config/src/androidMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfigValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import com.google.firebase.remoteconfig.FirebaseRemoteConfig 4 | import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue as AndroidFirebaseRemoteConfigValue 5 | 6 | public actual class FirebaseRemoteConfigValue internal constructor( 7 | private val android: AndroidFirebaseRemoteConfigValue, 8 | ) { 9 | public actual fun asBoolean(): Boolean = android.asBoolean() 10 | public actual fun asByteArray(): ByteArray = android.asByteArray() 11 | public actual fun asDouble(): Double = android.asDouble() 12 | public actual fun asLong(): Long = android.asLong() 13 | public actual fun asString(): String = android.asString() 14 | public actual fun getSource(): ValueSource = when (android.source) { 15 | FirebaseRemoteConfig.VALUE_SOURCE_STATIC -> ValueSource.Static 16 | FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT -> ValueSource.Default 17 | FirebaseRemoteConfig.VALUE_SOURCE_REMOTE -> ValueSource.Remote 18 | else -> error("Unknown value source:${android.source}") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-config/src/androidUnitTest/kotlin/dev/gitlive/firebase/remoteconfig/RemoteConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.remoteconfig 8 | 9 | import org.junit.Ignore 10 | 11 | actual val context: Any = "" 12 | 13 | actual typealias IgnoreForAndroidUnitTest = Ignore 14 | -------------------------------------------------------------------------------- /firebase-config/src/commonMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfigSettings.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import kotlin.time.Duration 4 | import kotlin.time.Duration.Companion.hours 5 | import kotlin.time.Duration.Companion.minutes 6 | import kotlin.time.Duration.Companion.seconds 7 | 8 | private val CONNECTION_TIMEOUT = 1.minutes 9 | 10 | // https://firebase.google.com/docs/remote-config/get-started?hl=en&platform=android#throttling 11 | private val DEFAULT_FETCH_INTERVAL = 12.hours 12 | 13 | /** Wraps the settings for [FirebaseRemoteConfig] operations. */ 14 | public data class FirebaseRemoteConfigSettings( 15 | /** 16 | * Returns the fetch timeout in seconds. 17 | * 18 | * The timeout specifies how long the client should wait for a connection to the Firebase 19 | * Remote Config server. 20 | */ 21 | var fetchTimeout: Duration = CONNECTION_TIMEOUT, 22 | 23 | /** Returns the minimum interval between successive fetches calls in seconds. */ 24 | var minimumFetchInterval: Duration = DEFAULT_FETCH_INTERVAL, 25 | ) { 26 | 27 | @Deprecated("Replaced with Kotlin Duration", replaceWith = ReplaceWith("fetchTimeout")) 28 | public var fetchTimeoutInSeconds: Long 29 | get() = fetchTimeout.inWholeSeconds 30 | set(value) { 31 | fetchTimeout = value.seconds 32 | } 33 | 34 | @Deprecated("Replaced with Kotlin Duration", replaceWith = ReplaceWith("minimumFetchInterval")) 35 | public var minimumFetchIntervalInSeconds: Long 36 | get() = minimumFetchInterval.inWholeSeconds 37 | set(value) { 38 | minimumFetchInterval = value.seconds 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /firebase-config/src/commonMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfigValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | /** Wrapper for a Remote Config parameter value, with methods to get it as different types. */ 4 | public expect class FirebaseRemoteConfigValue { 5 | /** 6 | * Gets the value as a [Boolean]. 7 | * 8 | * @return [Boolean] representation of this parameter value. 9 | */ 10 | public fun asBoolean(): Boolean 11 | 12 | /** 13 | * Gets the value as a [ByteArray]. 14 | * 15 | * @return [ByteArray] representation of this parameter value. 16 | */ 17 | public fun asByteArray(): ByteArray 18 | 19 | /** 20 | * Gets the value as a [Double]. 21 | * 22 | * @return [Double] representation of this parameter value. 23 | */ 24 | public fun asDouble(): Double 25 | 26 | /** 27 | * Gets the value as a [Long]. 28 | * 29 | * @return [Long] representation of this parameter value. 30 | */ 31 | public fun asLong(): Long 32 | 33 | /** 34 | * Gets the value as a [String]. 35 | * 36 | * @return [String] representation of this parameter value. 37 | */ 38 | public fun asString(): String 39 | 40 | /** 41 | * Indicates at which source this value came from. 42 | * 43 | * @return [ValueSource.Remote] if the value was retrieved from the server, [ValueSource.Default] if the value was set as a default, or [ValueSource.Stataic] if no value was found and a static default value was returned instead. 44 | */ 45 | public fun getSource(): ValueSource 46 | } 47 | 48 | public enum class ValueSource { 49 | /** Indicates that the value returned is the static default value. */ 50 | Static, 51 | 52 | /** Indicates that the value returned was retrieved from the defaults set by the client. */ 53 | Default, 54 | 55 | /** Indicates that the value returned was retrieved from the Firebase Remote Config server. */ 56 | Remote, 57 | } 58 | -------------------------------------------------------------------------------- /firebase-config/src/iosMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfigValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import cocoapods.FirebaseRemoteConfig.FIRRemoteConfigSource 4 | import cocoapods.FirebaseRemoteConfig.FIRRemoteConfigValue 5 | 6 | public actual class FirebaseRemoteConfigValue internal constructor(private val ios: FIRRemoteConfigValue) { 7 | @ExperimentalUnsignedTypes 8 | public actual fun asByteArray(): ByteArray = ios.dataValue.toByteArray() 9 | 10 | public actual fun asBoolean(): Boolean = ios.boolValue 11 | public actual fun asDouble(): Double = ios.numberValue.doubleValue 12 | public actual fun asLong(): Long = ios.numberValue.longValue 13 | public actual fun asString(): String = ios.stringValue ?: "" 14 | public actual fun getSource(): ValueSource = when (ios.source) { 15 | FIRRemoteConfigSource.FIRRemoteConfigSourceStatic -> ValueSource.Static 16 | FIRRemoteConfigSource.FIRRemoteConfigSourceDefault -> ValueSource.Default 17 | FIRRemoteConfigSource.FIRRemoteConfigSourceRemote -> ValueSource.Remote 18 | else -> error("Unknown value source:${ios.source}") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-config/src/iosMain/kotlin/dev/gitlive/firebase/remoteconfig/NSDataExtension.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import kotlinx.cinterop.addressOf 4 | import kotlinx.cinterop.usePinned 5 | import platform.Foundation.NSData 6 | import platform.posix.memcpy 7 | 8 | @ExperimentalUnsignedTypes 9 | public fun NSData.toByteArray(): ByteArray = ByteArray(length.toInt()).apply { 10 | usePinned { memcpy(it.addressOf(0), bytes, length) } 11 | } 12 | -------------------------------------------------------------------------------- /firebase-config/src/iosTest/kotlin/dev/gitlive/firebase/remoteconfig/NSDataExtensionTest.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import platform.Foundation.NSString 4 | import platform.Foundation.NSUTF8StringEncoding 5 | import platform.Foundation.create 6 | import platform.Foundation.dataUsingEncoding 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | @ExperimentalUnsignedTypes 11 | class NSDataExtensionTest { 12 | @Test 13 | fun testNSDataToByteArray() { 14 | val nsData = NSString 15 | .create(string = "Hello world") 16 | .dataUsingEncoding(NSUTF8StringEncoding)!! 17 | assertEquals("Hello world", nsData.toByteArray().decodeToString()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-config/src/iosTest/kotlin/dev/gitlive/firebase/remoteconfig/RemoteConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.remoteconfig 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-config/src/jsMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfigValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | import dev.gitlive.firebase.remoteconfig.externals.Value 4 | 5 | public val FirebaseRemoteConfigValue.js get() = js 6 | 7 | public actual class FirebaseRemoteConfigValue(internal val js: Value) { 8 | public actual fun asBoolean(): Boolean = rethrow { js.asBoolean() } 9 | public actual fun asByteArray(): ByteArray = rethrow { js.asString()?.encodeToByteArray() ?: byteArrayOf() } 10 | public actual fun asDouble(): Double = rethrow { js.asNumber().toDouble() } 11 | public actual fun asLong(): Long = rethrow { js.asNumber().toLong() } 12 | public actual fun asString(): String = rethrow { js.asString() ?: "" } 13 | public actual fun getSource(): ValueSource = rethrow { js.getSource().toSource() } 14 | 15 | private fun String.toSource() = when (this) { 16 | "default" -> ValueSource.Default 17 | "remote" -> ValueSource.Remote 18 | "static" -> ValueSource.Static 19 | else -> error("Unknown ValueSource: $this") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /firebase-config/src/jsMain/kotlin/dev/gitlive/firebase/remoteconfig/externals/remoteconfig.kt: -------------------------------------------------------------------------------- 1 | @file:JsModule("firebase/remote-config") 2 | @file:JsNonModule 3 | 4 | package dev.gitlive.firebase.remoteconfig.externals 5 | 6 | import dev.gitlive.firebase.externals.FirebaseApp 7 | import kotlin.js.Json 8 | import kotlin.js.Promise 9 | 10 | public external fun activate(remoteConfig: RemoteConfig): Promise 11 | 12 | public external fun ensureInitialized(remoteConfig: RemoteConfig): Promise 13 | 14 | public external fun fetchAndActivate(remoteConfig: RemoteConfig): Promise 15 | 16 | public external fun fetchConfig(remoteConfig: RemoteConfig): Promise 17 | 18 | public external fun getAll(remoteConfig: RemoteConfig): Json 19 | 20 | public external fun getBoolean(remoteConfig: RemoteConfig, key: String): Boolean 21 | 22 | public external fun getNumber(remoteConfig: RemoteConfig, key: String): Number 23 | 24 | public external fun getRemoteConfig(app: FirebaseApp? = definedExternally): RemoteConfig 25 | 26 | public external fun getString(remoteConfig: RemoteConfig, key: String): String? 27 | 28 | public external fun getValue(remoteConfig: RemoteConfig, key: String): Value 29 | 30 | public external interface RemoteConfig { 31 | public var defaultConfig: Any 32 | public var fetchTimeMillis: Double 33 | public var lastFetchStatus: String 34 | public val settings: Settings 35 | } 36 | 37 | public external interface Settings { 38 | public var fetchTimeoutMillis: Number 39 | public var minimumFetchIntervalMillis: Number 40 | } 41 | 42 | public external interface Value { 43 | public fun asBoolean(): Boolean 44 | public fun asNumber(): Number 45 | public fun asString(): String? 46 | public fun getSource(): String 47 | } 48 | -------------------------------------------------------------------------------- /firebase-config/src/jsTest/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfig.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.remoteconfig 2 | 3 | actual val context: Any = Unit 4 | 5 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 6 | actual annotation class IgnoreForAndroidUnitTest 7 | -------------------------------------------------------------------------------- /firebase-config/src/jvmTest/kotlin/dev/gitlive/firebase/remoteconfig/RemoteConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.remoteconfig 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val context: Any = testContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-crashlytics/api/firebase-crashlytics.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/crashlytics/CrashlyticsKt { 2 | public static final fun crashlytics (Ldev/gitlive/firebase/Firebase;Ldev/gitlive/firebase/FirebaseApp;)Ldev/gitlive/firebase/crashlytics/FirebaseCrashlytics; 3 | public static final fun getAndroid (Ldev/gitlive/firebase/crashlytics/FirebaseCrashlytics;)Lcom/google/firebase/crashlytics/FirebaseCrashlytics; 4 | public static final fun getCrashlytics (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/crashlytics/FirebaseCrashlytics; 5 | } 6 | 7 | public final class dev/gitlive/firebase/crashlytics/FirebaseCrashlytics { 8 | public final fun deleteUnsentReports ()V 9 | public final fun didCrashOnPreviousExecution ()Z 10 | public final fun log (Ljava/lang/String;)V 11 | public final fun recordException (Ljava/lang/Throwable;)V 12 | public final fun sendUnsentReports ()V 13 | public final fun setCrashlyticsCollectionEnabled (Z)V 14 | public final fun setCustomKey (Ljava/lang/String;D)V 15 | public final fun setCustomKey (Ljava/lang/String;F)V 16 | public final fun setCustomKey (Ljava/lang/String;I)V 17 | public final fun setCustomKey (Ljava/lang/String;J)V 18 | public final fun setCustomKey (Ljava/lang/String;Ljava/lang/String;)V 19 | public final fun setCustomKey (Ljava/lang/String;Z)V 20 | public final fun setCustomKeys (Ljava/util/Map;)V 21 | public final fun setUserId (Ljava/lang/String;)V 22 | } 23 | 24 | public class dev/gitlive/firebase/crashlytics/FirebaseCrashlyticsException : com/google/firebase/FirebaseException { 25 | public fun (Ljava/lang/String;)V 26 | } 27 | 28 | -------------------------------------------------------------------------------- /firebase-crashlytics/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-crashlytics 2 | This module is a direct forward of the Firebase Crashlytics library. It provides the main functionality, like logging crashes to crashlytics. -------------------------------------------------------------------------------- /firebase-crashlytics/firebase_crashlytics.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_crashlytics' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_crashlytics.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-crashlytics', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_crashlytics', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_crashlytics', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-crashlytics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-crashlytics", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-crashlytics.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.6.10", 29 | "kotlinx-coroutines-core": "1.6.1-native-mt" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.crashlytics 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/androidInstrumentedTest/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/androidUnitTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.crashlytics 8 | 9 | import org.junit.Ignore 10 | 11 | actual val context: Any = "" 12 | 13 | actual typealias IgnoreForAndroidUnitTest = Ignore 14 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/iosTest/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.crashlytics 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-crashlytics/src/jvmMain/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.jvm.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.crashlytics 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.FirebaseException 6 | 7 | /** Returns the [FirebaseCrashlytics] instance of the default [FirebaseApp]. */ 8 | actual val Firebase.crashlytics: FirebaseCrashlytics 9 | get() = TODO("Not yet implemented") 10 | 11 | /** Returns the [FirebaseCrashlytics] instance of a given [FirebaseApp]. */ 12 | actual fun Firebase.crashlytics(app: FirebaseApp): FirebaseCrashlytics { 13 | TODO("Not yet implemented") 14 | } 15 | 16 | actual class FirebaseCrashlytics { 17 | actual fun recordException(exception: Throwable) { 18 | } 19 | 20 | actual fun log(message: String) { 21 | } 22 | 23 | actual fun setUserId(userId: String) { 24 | } 25 | 26 | actual fun setCustomKey(key: String, value: String) { 27 | } 28 | 29 | actual fun setCustomKey(key: String, value: Boolean) { 30 | } 31 | 32 | actual fun setCustomKey(key: String, value: Double) { 33 | } 34 | 35 | actual fun setCustomKey(key: String, value: Float) { 36 | } 37 | 38 | actual fun setCustomKey(key: String, value: Int) { 39 | } 40 | 41 | actual fun setCustomKey(key: String, value: Long) { 42 | } 43 | 44 | actual fun setCustomKeys(customKeys: Map) { 45 | } 46 | 47 | actual fun setCrashlyticsCollectionEnabled(enabled: Boolean) { 48 | } 49 | 50 | actual fun didCrashOnPreviousExecution(): Boolean { 51 | TODO("Not yet implemented") 52 | } 53 | 54 | actual fun sendUnsentReports() { 55 | } 56 | 57 | actual fun deleteUnsentReports() { 58 | } 59 | } 60 | 61 | actual open class FirebaseCrashlyticsException internal constructor(message: String) : FirebaseException(message) -------------------------------------------------------------------------------- /firebase-database/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-database 2 | This module is a direct forward of the Firebase Database library. It provides the main functionality, like storing data. -------------------------------------------------------------------------------- /firebase-database/firebase_database.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_database' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_database.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-database', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_database', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_database', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-database/karma.config.d/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Some tests are fluky in GitHub Actions, so we increase the timeout. 2 | config.set({ 3 | client: { 4 | mocha: { 5 | timeout: 180000 6 | } 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /firebase-database/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-database", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-database.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-database/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/database/database.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.database 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | import org.junit.Ignore 11 | 12 | actual val emulatorHost: String = "10.0.2.2" 13 | 14 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 15 | 16 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 17 | actual annotation class IgnoreForAndroidUnitTest 18 | 19 | actual typealias IgnoreForAndroidTest = Ignore 20 | -------------------------------------------------------------------------------- /firebase-database/src/androidMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.database 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | private typealias NativeServerValue = com.google.firebase.database.ServerValue 6 | 7 | /** Represents a Firebase ServerValue. */ 8 | @Serializable(with = ServerValueSerializer::class) 9 | public actual class ServerValue internal actual constructor( 10 | internal actual val nativeValue: Any, 11 | ) { 12 | public actual companion object { 13 | public actual val TIMESTAMP: ServerValue get() = ServerValue(NativeServerValue.TIMESTAMP) 14 | public actual fun increment(delta: Double): ServerValue = ServerValue(NativeServerValue.increment(delta)) 15 | } 16 | 17 | override fun equals(other: Any?): Boolean = 18 | this === other || other is ServerValue && nativeValue == other.nativeValue 19 | override fun hashCode(): Int = nativeValue.hashCode() 20 | override fun toString(): String = "ServerValue($nativeValue)" 21 | } 22 | -------------------------------------------------------------------------------- /firebase-database/src/androidUnitTest/kotlin/dev/gitlive/firebase/database/database.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.database 8 | 9 | import org.junit.Ignore 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = "" 14 | actual typealias IgnoreForAndroidUnitTest = Ignore 15 | actual typealias IgnoreForAndroidTest = Ignore 16 | -------------------------------------------------------------------------------- /firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.database 2 | 3 | import dev.gitlive.firebase.internal.FirebaseDecoder 4 | import dev.gitlive.firebase.internal.FirebaseEncoder 5 | import dev.gitlive.firebase.internal.SpecialValueSerializer 6 | import kotlinx.serialization.KSerializer 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.SerializationException 9 | 10 | /** Represents a Firebase ServerValue. */ 11 | @Serializable(with = ServerValueSerializer::class) 12 | public expect class ServerValue internal constructor(nativeValue: Any) { 13 | internal val nativeValue: Any 14 | 15 | public companion object { 16 | public val TIMESTAMP: ServerValue 17 | public fun increment(delta: Double): ServerValue 18 | } 19 | } 20 | 21 | /** Serializer for [ServerValue]. Must be used with [FirebaseEncoder]/[FirebaseDecoder].*/ 22 | public object ServerValueSerializer : KSerializer by SpecialValueSerializer( 23 | serialName = "ServerValue", 24 | toNativeValue = ServerValue::nativeValue, 25 | fromNativeValue = { raw -> 26 | raw?.let(::ServerValue) ?: throw SerializationException("Cannot deserialize $raw") 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /firebase-database/src/iosMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.database 2 | 3 | import cocoapods.FirebaseDatabase.FIRServerValue 4 | import kotlinx.serialization.Serializable 5 | import platform.Foundation.NSNumber 6 | 7 | private typealias NativeServerValue = FIRServerValue 8 | 9 | /** Represents a Firebase ServerValue. */ 10 | @Serializable(with = ServerValueSerializer::class) 11 | public actual class ServerValue internal actual constructor( 12 | internal actual val nativeValue: Any, 13 | ) { 14 | public actual companion object { 15 | public actual val TIMESTAMP: ServerValue get() = ServerValue(NativeServerValue.timestamp()) 16 | 17 | @Suppress("CAST_NEVER_SUCCEEDS") 18 | public actual fun increment(delta: Double): ServerValue = ServerValue(NativeServerValue.increment(delta as NSNumber)) 19 | } 20 | 21 | override fun equals(other: Any?): Boolean = 22 | this === other || other is ServerValue && nativeValue == other.nativeValue 23 | override fun hashCode(): Int = nativeValue.hashCode() 24 | override fun toString(): String = "ServerValue($nativeValue)" 25 | } 26 | -------------------------------------------------------------------------------- /firebase-database/src/iosTest/kotlin/dev/gitlive/firebase/database/database.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.database 6 | 7 | actual val emulatorHost: String = "localhost" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | 14 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 15 | actual annotation class IgnoreForAndroidTest 16 | -------------------------------------------------------------------------------- /firebase-database/src/jsMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.database 2 | 3 | import dev.gitlive.firebase.database.externals.serverTimestamp 4 | import kotlinx.serialization.Serializable 5 | import dev.gitlive.firebase.database.externals.increment as jsIncrement 6 | 7 | /** Represents a Firebase ServerValue. */ 8 | @Serializable(with = ServerValueSerializer::class) 9 | public actual class ServerValue internal actual constructor( 10 | internal actual val nativeValue: Any, 11 | ) { 12 | public actual companion object { 13 | public actual val TIMESTAMP: ServerValue get() = ServerValue(serverTimestamp()) 14 | public actual fun increment(delta: Double): ServerValue = ServerValue(jsIncrement(delta)) 15 | } 16 | 17 | override fun equals(other: Any?): Boolean = 18 | this === other || other is ServerValue && nativeValue == other.nativeValue 19 | override fun hashCode(): Int = nativeValue.hashCode() 20 | override fun toString(): String = "ServerValue($nativeValue)" 21 | } 22 | -------------------------------------------------------------------------------- /firebase-database/src/jsMain/kotlin/dev/gitlive/firebase/database/externals/callbacks.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.database.externals 6 | 7 | public typealias ChangeSnapshotCallback = (data: DataSnapshot, previousChildName: String?) -> Unit 8 | public typealias ValueSnapshotCallback = (data: DataSnapshot) -> Unit 9 | public typealias CancelCallback = (error: Throwable) -> Unit 10 | -------------------------------------------------------------------------------- /firebase-database/src/jsTest/kotlin/dev/gitlive/firebase/database/database.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.database 2 | 3 | actual val emulatorHost: String = "127.0.0.1" // in JS tests connection is refused if we use localhost 4 | 5 | actual val context: Any = Unit 6 | 7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 8 | actual annotation class IgnoreForAndroidUnitTest 9 | 10 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 11 | actual annotation class IgnoreForAndroidTest 12 | -------------------------------------------------------------------------------- /firebase-database/src/jvmTest/kotlin/dev/gitlive/firebase/database/database.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.database 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val emulatorHost: String = "localhost" 12 | 13 | actual val context: Any = testContext 14 | 15 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 16 | actual annotation class IgnoreForAndroidUnitTest 17 | 18 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 19 | actual annotation class IgnoreForAndroidTest 20 | -------------------------------------------------------------------------------- /firebase-firestore/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-firestore 2 | This module is a direct forward of the Firebase Firestore library. It provides the main functionality, like storing data. -------------------------------------------------------------------------------- /firebase-firestore/firebase_firestore.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_firestore' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_firestore.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-firestore', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_firestore', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_firestore', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-firestore/karma.config.d/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Some tests are fluky in GitHub Actions, so we increase the timeout. 2 | config.set({ 3 | client: { 4 | mocha: { 5 | timeout: 1800000 6 | } 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /firebase-firestore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-firestore", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-firestore.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 4 | actual annotation class IgnoreJs 5 | 6 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 7 | actual annotation class IgnoreForAndroidUnitTest 8 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.firestore 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 14 | 15 | @Suppress("UNCHECKED_CAST") 16 | actual fun encodedAsMap(encoded: Any?): Map = encoded as Map 17 | actual fun Map.asEncoded(): Any = this 18 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/FieldValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** Represents a platform specific Firebase FieldValue. */ 6 | public typealias NativeFieldValue = com.google.firebase.firestore.FieldValue 7 | 8 | /** Represents a Firebase FieldValue. */ 9 | @Serializable(with = FieldValueSerializer::class) 10 | public actual class FieldValue internal actual constructor(internal actual val nativeValue: Any) { 11 | init { 12 | require(nativeValue is NativeFieldValue) 13 | } 14 | override fun equals(other: Any?): Boolean = 15 | this === other || other is FieldValue && nativeValue == other.nativeValue 16 | override fun hashCode(): Int = nativeValue.hashCode() 17 | override fun toString(): String = nativeValue.toString() 18 | 19 | public actual companion object { 20 | public actual val serverTimestamp: FieldValue get() = FieldValue(NativeFieldValue.serverTimestamp()) 21 | public actual val delete: FieldValue get() = FieldValue(NativeFieldValue.delete()) 22 | public actual fun increment(value: Int): FieldValue = FieldValue(NativeFieldValue.increment(value.toDouble())) 23 | public actual fun arrayUnion(vararg elements: Any): FieldValue = FieldValue(NativeFieldValue.arrayUnion(*elements)) 24 | public actual fun arrayRemove(vararg elements: Any): FieldValue = FieldValue(NativeFieldValue.arrayRemove(*elements)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/GeoPoint.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** A class representing a platform specific Firebase GeoPoint. */ 6 | public actual typealias NativeGeoPoint = com.google.firebase.firestore.GeoPoint 7 | 8 | /** A class representing a Firebase GeoPoint. */ 9 | @Serializable(with = GeoPointSerializer::class) 10 | public actual class GeoPoint internal actual constructor(internal actual val nativeValue: NativeGeoPoint) { 11 | public actual constructor(latitude: Double, longitude: Double) : this(NativeGeoPoint(latitude, longitude)) 12 | public actual val latitude: Double = nativeValue.latitude 13 | public actual val longitude: Double = nativeValue.longitude 14 | 15 | override fun equals(other: Any?): Boolean = 16 | this === other || other is GeoPoint && nativeValue == other.nativeValue 17 | override fun hashCode(): Int = nativeValue.hashCode() 18 | override fun toString(): String = nativeValue.toString() 19 | } 20 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("androidTimestamp") 2 | 3 | package dev.gitlive.firebase.firestore 4 | 5 | import kotlinx.serialization.Serializable 6 | 7 | /** A class representing a platform specific Firebase Timestamp. */ 8 | public actual typealias NativeTimestamp = com.google.firebase.Timestamp 9 | 10 | /** A base class that could be used to combine [Timestamp] and [Timestamp.ServerTimestamp] in the same field. */ 11 | @Serializable(with = BaseTimestampSerializer::class) 12 | public actual sealed class BaseTimestamp 13 | 14 | /** A class representing a Firebase Timestamp. */ 15 | @Serializable(with = TimestampSerializer::class) 16 | public actual class Timestamp internal actual constructor( 17 | internal actual val nativeValue: NativeTimestamp, 18 | ) : BaseTimestamp() { 19 | public actual constructor(seconds: Long, nanoseconds: Int) : this(NativeTimestamp(seconds, nanoseconds)) 20 | 21 | public actual val seconds: Long = nativeValue.seconds 22 | public actual val nanoseconds: Int = nativeValue.nanoseconds 23 | 24 | override fun equals(other: Any?): Boolean = 25 | this === other || other is Timestamp && nativeValue == other.nativeValue 26 | override fun hashCode(): Int = nativeValue.hashCode() 27 | override fun toString(): String = nativeValue.toString() 28 | 29 | public actual companion object { 30 | public actual fun now(): Timestamp = Timestamp(NativeTimestamp.now()) 31 | } 32 | 33 | /** A server time timestamp. */ 34 | @Serializable(with = ServerTimestampSerializer::class) 35 | public actual data object ServerTimestamp : BaseTimestamp() 36 | } 37 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/_encoders.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | @PublishedApi 4 | internal actual fun isSpecialValue(value: Any): Boolean = when (value) { 5 | is NativeFieldValue, 6 | is NativeGeoPoint, 7 | is NativeTimestamp, 8 | is NativeDocumentReferenceType, 9 | -> true 10 | else -> false 11 | } 12 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeCollectionReferenceWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.NativeCollectionReference 4 | import dev.gitlive.firebase.internal.EncodedObject 5 | import dev.gitlive.firebase.internal.android 6 | import kotlinx.coroutines.tasks.await 7 | 8 | internal actual class NativeCollectionReferenceWrapper internal actual constructor(actual override val native: NativeCollectionReference) : NativeQueryWrapper(native) { 9 | 10 | actual val path: String 11 | get() = native.path 12 | 13 | actual val document: NativeDocumentReference 14 | get() = NativeDocumentReference(native.document()) 15 | 16 | actual val parent: NativeDocumentReference? 17 | get() = native.parent?.let { NativeDocumentReference(it) } 18 | 19 | actual fun document(documentPath: String) = 20 | NativeDocumentReference(native.document(documentPath)) 21 | 22 | actual suspend fun addEncoded(data: EncodedObject) = 23 | NativeDocumentReference(native.add(data.android).await()) 24 | } 25 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentSnapshotWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.EncodedFieldPath 4 | import dev.gitlive.firebase.firestore.ServerTimestampBehavior 5 | import dev.gitlive.firebase.firestore.SnapshotMetadata 6 | 7 | internal actual class NativeDocumentSnapshotWrapper internal actual constructor(actual val native: com.google.firebase.firestore.DocumentSnapshot) { 8 | 9 | actual val id get() = native.id 10 | actual val reference get() = NativeDocumentReference(native.reference) 11 | 12 | actual fun getEncoded(field: String, serverTimestampBehavior: ServerTimestampBehavior): Any? = native.get(field, serverTimestampBehavior.toAndroid()) 13 | actual fun getEncoded(fieldPath: EncodedFieldPath, serverTimestampBehavior: ServerTimestampBehavior): Any? = native.get(fieldPath, serverTimestampBehavior.toAndroid()) 14 | actual fun encodedData(serverTimestampBehavior: ServerTimestampBehavior): Any? = native.getData(serverTimestampBehavior.toAndroid()) 15 | 16 | actual fun contains(field: String) = native.contains(field) 17 | actual fun contains(fieldPath: EncodedFieldPath) = native.contains(fieldPath) 18 | 19 | actual val exists get() = native.exists() 20 | 21 | actual val metadata: SnapshotMetadata get() = SnapshotMetadata(native.metadata) 22 | 23 | fun ServerTimestampBehavior.toAndroid(): com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior = when (this) { 24 | ServerTimestampBehavior.ESTIMATE -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.ESTIMATE 25 | ServerTimestampBehavior.NONE -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.NONE 26 | ServerTimestampBehavior.PREVIOUS -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.PREVIOUS 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/SetOptions.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | internal val SetOptions.android: com.google.firebase.firestore.SetOptions? get() = when (this) { 4 | is SetOptions.Merge -> com.google.firebase.firestore.SetOptions.merge() 5 | is SetOptions.Overwrite -> null 6 | is SetOptions.MergeFields -> com.google.firebase.firestore.SetOptions.mergeFields(fields) 7 | is SetOptions.MergeFieldPaths -> com.google.firebase.firestore.SetOptions.mergeFieldPaths(encodedFieldPaths) 8 | } 9 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/Source.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.NativeSource 4 | import dev.gitlive.firebase.firestore.Source 5 | 6 | internal fun Source.toAndroidSource() = when (this) { 7 | Source.CACHE -> NativeSource.CACHE 8 | Source.SERVER -> NativeSource.SERVER 9 | Source.DEFAULT -> NativeSource.DEFAULT 10 | } 11 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/callbackExecutorMap.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import java.util.concurrent.ConcurrentHashMap 4 | import java.util.concurrent.Executor 5 | 6 | // Since on iOS Callback threads are set as settings, we store the settings explicitly here as well 7 | internal val callbackExecutorMap = ConcurrentHashMap() 8 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidUnitTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import org.junit.Ignore 4 | 5 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 6 | actual annotation class IgnoreJs 7 | actual typealias IgnoreForAndroidUnitTest = Ignore 8 | -------------------------------------------------------------------------------- /firebase-firestore/src/androidUnitTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.firestore 8 | 9 | actual val emulatorHost: String = "10.0.2.2" 10 | 11 | actual val context: Any = "" 12 | 13 | @Suppress("UNCHECKED_CAST") 14 | actual fun encodedAsMap(encoded: Any?): Map = encoded as Map 15 | actual fun Map.asEncoded(): Any = this 16 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceSerializer.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.firestore.internal.NativeDocumentReference 4 | import dev.gitlive.firebase.internal.FirebaseEncoder 5 | import dev.gitlive.firebase.internal.SpecialValueSerializer 6 | import kotlinx.serialization.KSerializer 7 | import kotlinx.serialization.SerializationException 8 | 9 | /** 10 | * A serializer for [DocumentReference]. If used with [FirebaseEncoder] performs serialization using native Firebase mechanisms. 11 | */ 12 | public object DocumentReferenceSerializer : KSerializer by SpecialValueSerializer( 13 | serialName = "DocumentReference", 14 | toNativeValue = { it.native.nativeValue }, 15 | fromNativeValue = { value -> 16 | when (value) { 17 | is NativeDocumentReferenceType -> DocumentReference(NativeDocumentReference(value)) 18 | else -> throw SerializationException("Cannot deserialize $value") 19 | } 20 | }, 21 | ) 22 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** Represents a Firebase FieldValue. */ 6 | @Serializable(with = FieldValueSerializer::class) 7 | public expect class FieldValue internal constructor(nativeValue: Any) { 8 | internal val nativeValue: Any 9 | 10 | public companion object { 11 | public val serverTimestamp: FieldValue 12 | public val delete: FieldValue 13 | public fun increment(value: Int): FieldValue 14 | public fun arrayUnion(vararg elements: Any): FieldValue 15 | public fun arrayRemove(vararg elements: Any): FieldValue 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueSerializer.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.internal.FirebaseEncoder 4 | import dev.gitlive.firebase.internal.SpecialValueSerializer 5 | import kotlinx.serialization.KSerializer 6 | import kotlinx.serialization.SerializationException 7 | 8 | /** A serializer for [FieldValue]. Must be used in conjunction with [FirebaseEncoder]. */ 9 | public object FieldValueSerializer : KSerializer by SpecialValueSerializer( 10 | serialName = "FieldValue", 11 | toNativeValue = FieldValue::nativeValue, 12 | fromNativeValue = { raw -> 13 | raw?.let(::FieldValue) ?: throw SerializationException("Cannot deserialize $raw") 14 | }, 15 | ) 16 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPoint.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** A class representing a platform specific Firebase GeoPoint. */ 6 | public expect class NativeGeoPoint 7 | 8 | /** A class representing a Firebase GeoPoint. */ 9 | @Serializable(with = GeoPointSerializer::class) 10 | public expect class GeoPoint internal constructor(nativeValue: NativeGeoPoint) { 11 | public constructor(latitude: Double, longitude: Double) 12 | public val latitude: Double 13 | public val longitude: Double 14 | internal val nativeValue: NativeGeoPoint 15 | } 16 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPointSerializer.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.internal.SpecialValueSerializer 4 | import kotlinx.serialization.KSerializer 5 | import kotlinx.serialization.SerializationException 6 | 7 | /** Serializer for [GeoPoint]. If used with [FirebaseEncoder] performs serialization using native Firebase mechanisms. */ 8 | public object GeoPointSerializer : KSerializer by SpecialValueSerializer( 9 | serialName = "GeoPoint", 10 | toNativeValue = GeoPoint::nativeValue, 11 | fromNativeValue = { value -> 12 | when (value) { 13 | is NativeGeoPoint -> GeoPoint(value) 14 | else -> throw SerializationException("Cannot deserialize $value") 15 | } 16 | }, 17 | ) 18 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | import kotlin.time.Duration 5 | import kotlin.time.Duration.Companion.milliseconds 6 | import kotlin.time.Duration.Companion.nanoseconds 7 | import kotlin.time.Duration.Companion.seconds 8 | import kotlin.time.DurationUnit 9 | 10 | /** A class representing a platform specific Firebase Timestamp. */ 11 | public expect class NativeTimestamp 12 | 13 | /** A base class that could be used to combine [Timestamp] and [Timestamp.ServerTimestamp] in the same field. */ 14 | @Serializable(with = BaseTimestampSerializer::class) 15 | public expect sealed class BaseTimestamp 16 | 17 | /** A class representing a Firebase Timestamp. */ 18 | @Serializable(with = TimestampSerializer::class) 19 | public expect class Timestamp internal constructor(nativeValue: NativeTimestamp) : BaseTimestamp { 20 | public constructor(seconds: Long, nanoseconds: Int) 21 | public val seconds: Long 22 | public val nanoseconds: Int 23 | 24 | internal val nativeValue: NativeTimestamp 25 | 26 | public companion object { 27 | /** @return a local time timestamp. */ 28 | public fun now(): Timestamp 29 | } 30 | 31 | /** A server time timestamp. */ 32 | @Serializable(with = ServerTimestampSerializer::class) 33 | public data object ServerTimestamp : BaseTimestamp 34 | } 35 | 36 | public fun Timestamp.Companion.fromDuration(duration: Duration): Timestamp = 37 | duration.toComponents { seconds, nanoseconds -> 38 | Timestamp(seconds, nanoseconds) 39 | } 40 | public fun Timestamp.toDuration(): Duration = seconds.seconds + nanoseconds.nanoseconds 41 | 42 | public fun Timestamp.Companion.fromMilliseconds(milliseconds: Double): Timestamp = fromDuration(milliseconds.milliseconds) 43 | public fun Timestamp.toMilliseconds(): Double = toDuration().toDouble(DurationUnit.MILLISECONDS) 44 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/encoders.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.EncodeSettings 4 | 5 | /** @return whether value is special and shouldn't be encoded/decoded. */ 6 | @PublishedApi 7 | internal expect fun isSpecialValue(value: Any): Boolean 8 | 9 | @PublishedApi 10 | internal inline fun encode(value: T, buildSettings: EncodeSettings.Builder.() -> Unit): Any? = 11 | if (value?.let(::isSpecialValue) == true) { 12 | value 13 | } else { 14 | dev.gitlive.firebase.internal.encode(value, buildSettings) 15 | } 16 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.EncodeSettings 4 | import kotlin.jvm.JvmName 5 | 6 | // ** Helper method to perform an update operation. */ 7 | @JvmName("performUpdateFields") 8 | @PublishedApi 9 | internal inline fun encodeFieldAndValue( 10 | fieldsAndValues: Array>, 11 | buildSettings: EncodeSettings.Builder.() -> Unit, 12 | ): List>? = encodeFieldAndValue(fieldsAndValues, encodeField = { it }, encodeValue = { encode(it, buildSettings) }) 13 | 14 | /** Helper method to perform an update operation. */ 15 | @JvmName("performUpdateFieldPaths") 16 | @PublishedApi 17 | internal inline fun encodeFieldAndValue( 18 | fieldsAndValues: Array>, 19 | buildSettings: EncodeSettings.Builder.() -> Unit, 20 | ): List>? = encodeFieldAndValue(fieldsAndValues, { it.encoded }, { encode(it, buildSettings) }) 21 | 22 | /** Helper method to perform an update operation in Android and JS. */ 23 | @PublishedApi 24 | internal inline fun encodeFieldAndValue( 25 | fieldsAndValues: Array>, 26 | encodeField: (T) -> K, 27 | encodeValue: (Any?) -> Any?, 28 | ): List>? = 29 | fieldsAndValues.takeUnless { fieldsAndValues.isEmpty() } 30 | ?.map { (field, value) -> encodeField(field) to value?.let { encodeValue(it) } } 31 | 32 | internal fun List>.performUpdate( 33 | update: (K, Any?, Array) -> R, 34 | ) = update( 35 | this[0].first, 36 | this[0].second, 37 | this.drop(1).flatMap { (field, value) -> listOf(field, value) }.toTypedArray(), 38 | ) 39 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeCollectionReferenceWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.NativeCollectionReference 4 | import dev.gitlive.firebase.internal.EncodedObject 5 | 6 | internal expect class NativeCollectionReferenceWrapper internal constructor(native: NativeCollectionReference) : NativeQueryWrapper { 7 | 8 | override val native: NativeCollectionReference 9 | 10 | val path: String 11 | val document: NativeDocumentReference 12 | val parent: NativeDocumentReference? 13 | 14 | fun document(documentPath: String): NativeDocumentReference 15 | suspend fun addEncoded(data: EncodedObject): NativeDocumentReference 16 | } 17 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.EncodedFieldPath 4 | import dev.gitlive.firebase.firestore.NativeCollectionReference 5 | import dev.gitlive.firebase.firestore.NativeDocumentReferenceType 6 | import dev.gitlive.firebase.firestore.NativeDocumentSnapshot 7 | import dev.gitlive.firebase.firestore.Source 8 | import dev.gitlive.firebase.internal.EncodedObject 9 | import kotlinx.coroutines.flow.Flow 10 | 11 | internal expect class NativeDocumentReference(nativeValue: NativeDocumentReferenceType) { 12 | val nativeValue: NativeDocumentReferenceType 13 | val id: String 14 | val path: String 15 | val snapshots: Flow 16 | val parent: NativeCollectionReferenceWrapper 17 | fun snapshots(includeMetadataChanges: Boolean = false): Flow 18 | 19 | fun collection(collectionPath: String): NativeCollectionReference 20 | suspend fun get(source: Source = Source.DEFAULT): NativeDocumentSnapshot 21 | suspend fun setEncoded(encodedData: EncodedObject, setOptions: SetOptions) 22 | suspend fun updateEncoded(encodedData: EncodedObject) 23 | suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) 24 | suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) 25 | suspend fun delete() 26 | } 27 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentSnapshotWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.EncodedFieldPath 4 | import dev.gitlive.firebase.firestore.NativeDocumentSnapshot 5 | import dev.gitlive.firebase.firestore.ServerTimestampBehavior 6 | import dev.gitlive.firebase.firestore.SnapshotMetadata 7 | 8 | internal expect class NativeDocumentSnapshotWrapper internal constructor(native: NativeDocumentSnapshot) { 9 | 10 | val native: NativeDocumentSnapshot 11 | 12 | val exists: Boolean 13 | val id: String 14 | val reference: NativeDocumentReference 15 | val metadata: SnapshotMetadata 16 | 17 | fun contains(field: String): Boolean 18 | fun contains(fieldPath: EncodedFieldPath): Boolean 19 | 20 | fun getEncoded(field: String, serverTimestampBehavior: ServerTimestampBehavior = ServerTimestampBehavior.NONE): Any? 21 | fun getEncoded(fieldPath: EncodedFieldPath, serverTimestampBehavior: ServerTimestampBehavior = ServerTimestampBehavior.NONE): Any? 22 | fun encodedData(serverTimestampBehavior: ServerTimestampBehavior = ServerTimestampBehavior.NONE): Any? 23 | } 24 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeFirebaseFirestoreWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.FirebaseFirestoreSettings 4 | import dev.gitlive.firebase.firestore.NativeCollectionReference 5 | import dev.gitlive.firebase.firestore.NativeFirebaseFirestore 6 | import dev.gitlive.firebase.firestore.NativeQuery 7 | import dev.gitlive.firebase.firestore.NativeTransaction 8 | import dev.gitlive.firebase.firestore.NativeWriteBatch 9 | 10 | internal expect class NativeFirebaseFirestoreWrapper internal constructor(native: NativeFirebaseFirestore) { 11 | val native: NativeFirebaseFirestore 12 | 13 | fun collection(collectionPath: String): NativeCollectionReference 14 | fun collectionGroup(collectionId: String): NativeQuery 15 | fun document(documentPath: String): NativeDocumentReference 16 | fun batch(): NativeWriteBatch 17 | fun setLoggingEnabled(loggingEnabled: Boolean) 18 | fun applySettings(settings: FirebaseFirestoreSettings) 19 | suspend fun clearPersistence() 20 | suspend fun runTransaction(func: suspend NativeTransaction.() -> T): T 21 | fun useEmulator(host: String, port: Int) 22 | suspend fun disableNetwork() 23 | suspend fun enableNetwork() 24 | } 25 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.Direction 4 | import dev.gitlive.firebase.firestore.EncodedFieldPath 5 | import dev.gitlive.firebase.firestore.Filter 6 | import dev.gitlive.firebase.firestore.NativeDocumentSnapshot 7 | import dev.gitlive.firebase.firestore.NativeQuery 8 | import dev.gitlive.firebase.firestore.QuerySnapshot 9 | import dev.gitlive.firebase.firestore.Source 10 | import kotlinx.coroutines.flow.Flow 11 | 12 | internal expect open class NativeQueryWrapper internal constructor(native: NativeQuery) { 13 | 14 | open val native: NativeQuery 15 | 16 | fun limit(limit: Number): NativeQuery 17 | val snapshots: Flow 18 | fun snapshots(includeMetadataChanges: Boolean = false): Flow 19 | suspend fun get(source: Source = Source.DEFAULT): QuerySnapshot 20 | 21 | fun where(filter: Filter): NativeQuery 22 | 23 | fun orderBy(field: String, direction: Direction): NativeQuery 24 | fun orderBy(field: EncodedFieldPath, direction: Direction): NativeQuery 25 | 26 | fun startAfter(document: NativeDocumentSnapshot): NativeQuery 27 | fun startAfter(vararg fieldValues: Any): NativeQuery 28 | fun startAt(document: NativeDocumentSnapshot): NativeQuery 29 | fun startAt(vararg fieldValues: Any): NativeQuery 30 | 31 | fun endBefore(document: NativeDocumentSnapshot): NativeQuery 32 | fun endBefore(vararg fieldValues: Any): NativeQuery 33 | fun endAt(document: NativeDocumentSnapshot): NativeQuery 34 | fun endAt(vararg fieldValues: Any): NativeQuery 35 | } 36 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.DocumentReference 4 | import dev.gitlive.firebase.firestore.EncodedFieldPath 5 | import dev.gitlive.firebase.firestore.NativeTransaction 6 | import dev.gitlive.firebase.internal.EncodedObject 7 | 8 | internal expect class NativeTransactionWrapper internal constructor(native: NativeTransaction) { 9 | 10 | val native: NativeTransaction 11 | 12 | fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): NativeTransactionWrapper 13 | fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeTransactionWrapper 14 | fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeTransactionWrapper 15 | fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeTransactionWrapper 16 | fun delete(documentRef: DocumentReference): NativeTransactionWrapper 17 | suspend fun get(documentRef: DocumentReference): NativeDocumentSnapshotWrapper 18 | } 19 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.DocumentReference 4 | import dev.gitlive.firebase.firestore.EncodedFieldPath 5 | import dev.gitlive.firebase.firestore.NativeWriteBatch 6 | import dev.gitlive.firebase.internal.EncodedObject 7 | 8 | internal expect class NativeWriteBatchWrapper internal constructor(native: NativeWriteBatch) { 9 | val native: NativeWriteBatch 10 | fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): NativeWriteBatchWrapper 11 | fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeWriteBatchWrapper 12 | fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeWriteBatchWrapper 13 | fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeWriteBatchWrapper 14 | fun delete(documentRef: DocumentReference): NativeWriteBatchWrapper 15 | suspend fun commit() 16 | } 17 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SafeValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.DocumentReference 4 | import dev.gitlive.firebase.firestore.GeoPoint 5 | import dev.gitlive.firebase.firestore.Timestamp 6 | 7 | internal val Any.safeValue: Any get() = when (this) { 8 | is Timestamp -> nativeValue 9 | is GeoPoint -> nativeValue 10 | is DocumentReference -> native.nativeValue 11 | is Map<*, *> -> this.mapNotNull { (key, value) -> key?.let { it.safeValue to value?.safeValue } } 12 | is Collection<*> -> this.mapNotNull { it?.safeValue } 13 | else -> this 14 | } 15 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SetOptions.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.FieldPath 4 | 5 | @PublishedApi 6 | internal sealed class SetOptions { 7 | data object Merge : SetOptions() 8 | data object Overwrite : SetOptions() 9 | data class MergeFields(val fields: List) : SetOptions() 10 | data class MergeFieldPaths(val fieldPaths: List) : SetOptions() { 11 | val encodedFieldPaths = fieldPaths.map { it.encoded } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FieldValueTests.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.internal.firebaseSerializer 4 | import dev.gitlive.firebase.runTest 5 | import kotlin.test.Test 6 | import kotlin.test.assertEquals 7 | import kotlin.test.assertNotEquals 8 | 9 | class FieldValueTests { 10 | @Test 11 | fun equalityChecks() = runTest { 12 | assertEquals(FieldValue.delete, FieldValue.delete) 13 | assertEquals(FieldValue.serverTimestamp, FieldValue.serverTimestamp) 14 | assertNotEquals(FieldValue.delete, FieldValue.serverTimestamp) 15 | // Note: arrayUnion and arrayRemove can't be checked due to vararg to array conversion 16 | } 17 | 18 | @Test 19 | @IgnoreJs 20 | fun serializers() = runTest { 21 | assertEquals(FieldValueSerializer, FieldValue.delete.firebaseSerializer()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/GeoPointTests.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.internal.decode 4 | import dev.gitlive.firebase.internal.firebaseSerializer 5 | import dev.gitlive.firebase.runTest 6 | import kotlinx.serialization.Serializable 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | @Serializable 11 | data class TestDataWithGeoPoint( 12 | val uid: String, 13 | val location: GeoPoint, 14 | ) 15 | 16 | class GeoPointTests { 17 | 18 | @Test 19 | fun encodeGeoPointObject() = runTest { 20 | val geoPoint = GeoPoint(12.3, 45.6) 21 | val item = TestDataWithGeoPoint("123", geoPoint) 22 | val encoded = encodedAsMap( 23 | encode(item) { 24 | encodeDefaults = false 25 | }, 26 | ) 27 | assertEquals("123", encoded["uid"]) 28 | // check GeoPoint is encoded to a platform representation 29 | assertEquals(geoPoint.nativeValue, encoded["location"]) 30 | } 31 | 32 | @Test 33 | fun decodeGeoPointObject() = runTest { 34 | val geoPoint = GeoPoint(12.3, 45.6) 35 | val obj = mapOf( 36 | "uid" to "123", 37 | "location" to geoPoint.nativeValue, 38 | ).asEncoded() 39 | val decoded: TestDataWithGeoPoint = decode(obj) 40 | assertEquals("123", decoded.uid) 41 | // check a platform GeoPoint is properly wrapped 42 | assertEquals(geoPoint, decoded.location) 43 | } 44 | 45 | @Test 46 | @IgnoreJs 47 | fun serializers() = runTest { 48 | assertEquals(GeoPointSerializer, GeoPoint(0.0, 0.0).firebaseSerializer()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | /** Marker annotation to ignore JS test. */ 4 | expect annotation class IgnoreJs() 5 | expect annotation class IgnoreForAndroidUnitTest() 6 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/FieldValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import cocoapods.FirebaseFirestoreInternal.FIRFieldValue 4 | import kotlinx.serialization.Serializable 5 | 6 | /** A class representing a platform specific Firebase FieldValue. */ 7 | private typealias NativeFieldValue = FIRFieldValue 8 | 9 | /** Represents a Firebase FieldValue. */ 10 | @Serializable(with = FieldValueSerializer::class) 11 | public actual class FieldValue internal actual constructor(internal actual val nativeValue: Any) { 12 | init { 13 | require(nativeValue is NativeFieldValue) 14 | } 15 | override fun equals(other: Any?): Boolean = 16 | this === other || other is FieldValue && nativeValue == other.nativeValue 17 | override fun hashCode(): Int = nativeValue.hashCode() 18 | override fun toString(): String = nativeValue.toString() 19 | 20 | public actual companion object { 21 | public actual val serverTimestamp: FieldValue get() = FieldValue(NativeFieldValue.fieldValueForServerTimestamp()) 22 | public actual val delete: FieldValue get() = FieldValue(NativeFieldValue.fieldValueForDelete()) 23 | public actual fun increment(value: Int): FieldValue = FieldValue(NativeFieldValue.fieldValueForIntegerIncrement(value.toLong())) 24 | public actual fun arrayUnion(vararg elements: Any): FieldValue = FieldValue(NativeFieldValue.fieldValueForArrayUnion(elements.asList())) 25 | public actual fun arrayRemove(vararg elements: Any): FieldValue = FieldValue(NativeFieldValue.fieldValueForArrayRemove(elements.asList())) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/GeoPoint.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import cocoapods.FirebaseFirestoreInternal.FIRGeoPoint 4 | import kotlinx.serialization.Serializable 5 | 6 | /** A class representing a platform specific Firebase GeoPoint. */ 7 | public actual typealias NativeGeoPoint = FIRGeoPoint 8 | 9 | /** A class representing a Firebase GeoPoint. */ 10 | @Serializable(with = GeoPointSerializer::class) 11 | public actual class GeoPoint internal actual constructor(internal actual val nativeValue: NativeGeoPoint) { 12 | public actual constructor(latitude: Double, longitude: Double) : this(NativeGeoPoint(latitude, longitude)) 13 | public actual val latitude: Double = nativeValue.latitude 14 | public actual val longitude: Double = nativeValue.longitude 15 | 16 | override fun equals(other: Any?): Boolean = 17 | this === other || other is GeoPoint && nativeValue == other.nativeValue 18 | override fun hashCode(): Int = nativeValue.hashCode() 19 | override fun toString(): String = nativeValue.toString() 20 | } 21 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import cocoapods.FirebaseCore.FIRTimestamp 4 | import kotlinx.serialization.Serializable 5 | 6 | /** A class representing a platform specific Firebase Timestamp. */ 7 | public actual typealias NativeTimestamp = FIRTimestamp 8 | 9 | /** A base class that could be used to combine [Timestamp] and [Timestamp.ServerTimestamp] in the same field. */ 10 | @Serializable(with = BaseTimestampSerializer::class) 11 | public actual sealed class BaseTimestamp 12 | 13 | /** A class representing a Firebase Timestamp. */ 14 | @Serializable(with = TimestampSerializer::class) 15 | public actual class Timestamp internal actual constructor( 16 | internal actual val nativeValue: NativeTimestamp, 17 | ) : BaseTimestamp() { 18 | public actual constructor(seconds: Long, nanoseconds: Int) : this(NativeTimestamp(seconds, nanoseconds)) 19 | 20 | public actual val seconds: Long = nativeValue.seconds 21 | public actual val nanoseconds: Int = nativeValue.nanoseconds 22 | 23 | override fun equals(other: Any?): Boolean = 24 | this === other || other is Timestamp && nativeValue == other.nativeValue 25 | override fun hashCode(): Int = nativeValue.hashCode() 26 | override fun toString(): String = nativeValue.toString() 27 | 28 | public actual companion object { 29 | public actual fun now(): Timestamp = Timestamp(NativeTimestamp.timestamp()) 30 | } 31 | 32 | /** A server time timestamp. */ 33 | @Serializable(with = ServerTimestampSerializer::class) 34 | public actual object ServerTimestamp : BaseTimestamp() 35 | } 36 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/_encoders.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import cocoapods.FirebaseFirestoreInternal.FIRFieldValue 4 | 5 | @PublishedApi 6 | internal actual fun isSpecialValue(value: Any): Boolean = when (value) { 7 | is FIRFieldValue, 8 | is NativeGeoPoint, 9 | is NativeTimestamp, 10 | is NativeDocumentReferenceType, 11 | -> true 12 | else -> false 13 | } 14 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeCollectionReferenceWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.NativeCollectionReference 4 | import dev.gitlive.firebase.firestore.await 5 | import dev.gitlive.firebase.internal.EncodedObject 6 | import dev.gitlive.firebase.internal.ios 7 | 8 | internal actual class NativeCollectionReferenceWrapper internal actual constructor(actual override val native: NativeCollectionReference) : NativeQueryWrapper(native) { 9 | 10 | actual val path: String 11 | get() = native.path 12 | 13 | actual val document get() = NativeDocumentReference(native.documentWithAutoID()) 14 | 15 | actual val parent get() = native.parent?.let { NativeDocumentReference(it) } 16 | 17 | actual fun document(documentPath: String) = 18 | NativeDocumentReference(native.documentWithPath(documentPath)) 19 | 20 | actual suspend fun addEncoded(data: EncodedObject) = 21 | NativeDocumentReference(await { native.addDocumentWithData(data.ios, it) }) 22 | } 23 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/Source.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import cocoapods.FirebaseFirestoreInternal.FIRFirestoreSource 4 | import dev.gitlive.firebase.firestore.Source 5 | 6 | internal fun Source.toIosSource() = when (this) { 7 | Source.CACHE -> FIRFirestoreSource.FIRFirestoreSourceCache 8 | Source.SERVER -> FIRFirestoreSource.FIRFirestoreSourceServer 9 | Source.DEFAULT -> FIRFirestoreSource.FIRFirestoreSourceDefault 10 | } 11 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/throwError.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.toException 4 | import kotlinx.cinterop.CPointer 5 | import kotlinx.cinterop.ObjCObjectVar 6 | import kotlinx.cinterop.alloc 7 | import kotlinx.cinterop.memScoped 8 | import kotlinx.cinterop.pointed 9 | import kotlinx.cinterop.ptr 10 | import kotlinx.cinterop.value 11 | import platform.Foundation.NSError 12 | 13 | internal fun T.throwError(block: T.(errorPointer: CPointer>) -> R): R { 14 | memScoped { 15 | val errorPointer: CPointer> = alloc>().ptr 16 | val result = block(errorPointer) 17 | val error: NSError? = errorPointer.pointed.value 18 | if (error != null) { 19 | throw error.toException() 20 | } 21 | return result 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 4 | actual annotation class IgnoreJs 5 | 6 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 7 | actual annotation class IgnoreForAndroidUnitTest 8 | -------------------------------------------------------------------------------- /firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.firestore 6 | 7 | actual val emulatorHost: String = "localhost" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Suppress("UNCHECKED_CAST") 12 | actual fun encodedAsMap(encoded: Any?): Map = encoded as Map 13 | actual fun Map.asEncoded(): Any = this 14 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/FieldValue.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.firestore.externals.deleteField 4 | import kotlinx.serialization.Serializable 5 | import dev.gitlive.firebase.firestore.externals.serverTimestamp as jsServerTimestamp 6 | import dev.gitlive.firebase.firestore.externals.arrayRemove as jsArrayRemove 7 | import dev.gitlive.firebase.firestore.externals.arrayUnion as jsArrayUnion 8 | import dev.gitlive.firebase.firestore.externals.increment as jsIncrement 9 | 10 | /** Represents a platform specific Firebase FieldValue. */ 11 | public typealias NativeFieldValue = dev.gitlive.firebase.firestore.externals.FieldValue 12 | 13 | /** Represents a Firebase FieldValue. */ 14 | @Serializable(with = FieldValueSerializer::class) 15 | public actual class FieldValue internal actual constructor(internal actual val nativeValue: Any) { 16 | init { 17 | require(nativeValue is NativeFieldValue) 18 | } 19 | override fun equals(other: Any?): Boolean = 20 | this === other || 21 | other is FieldValue && 22 | (nativeValue as NativeFieldValue).isEqual(other.nativeValue as NativeFieldValue) 23 | override fun hashCode(): Int = nativeValue.hashCode() 24 | override fun toString(): String = nativeValue.toString() 25 | 26 | public actual companion object { 27 | public actual val serverTimestamp: FieldValue get() = rethrow { FieldValue(jsServerTimestamp()) } 28 | public actual val delete: FieldValue get() = rethrow { FieldValue(deleteField()) } 29 | public actual fun increment(value: Int): FieldValue = rethrow { FieldValue(jsIncrement(value)) } 30 | public actual fun arrayUnion(vararg elements: Any): FieldValue = rethrow { FieldValue(jsArrayUnion(*elements)) } 31 | public actual fun arrayRemove(vararg elements: Any): FieldValue = rethrow { FieldValue(jsArrayRemove(*elements)) } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/GeoPoint.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** A class representing a platform specific Firebase GeoPoint. */ 6 | public actual typealias NativeGeoPoint = dev.gitlive.firebase.firestore.externals.GeoPoint 7 | 8 | /** A class representing a Firebase GeoPoint. */ 9 | @Serializable(with = GeoPointSerializer::class) 10 | public actual class GeoPoint internal actual constructor(internal actual val nativeValue: NativeGeoPoint) { 11 | public actual constructor(latitude: Double, longitude: Double) : this(NativeGeoPoint(latitude, longitude)) 12 | public actual val latitude: Double by nativeValue::latitude 13 | public actual val longitude: Double by nativeValue::longitude 14 | 15 | override fun equals(other: Any?): Boolean = 16 | this === other || other is GeoPoint && nativeValue.isEqual(other.nativeValue) 17 | override fun hashCode(): Int = nativeValue.hashCode() 18 | override fun toString(): String = "GeoPoint[lat=$latitude,long=$longitude]" 19 | } 20 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | /** A base class that could be used to combine [Timestamp] and [Timestamp.ServerTimestamp] in the same field. */ 6 | @Serializable(with = BaseTimestampSerializer::class) 7 | public actual sealed class BaseTimestamp 8 | 9 | /** A class representing a platform specific Firebase Timestamp. */ 10 | public actual typealias NativeTimestamp = dev.gitlive.firebase.firestore.externals.Timestamp 11 | 12 | /** A class representing a Firebase Timestamp. */ 13 | @Serializable(with = TimestampSerializer::class) 14 | public actual class Timestamp internal actual constructor( 15 | internal actual val nativeValue: NativeTimestamp, 16 | ) : BaseTimestamp() { 17 | public actual constructor(seconds: Long, nanoseconds: Int) : this(NativeTimestamp(seconds.toDouble(), nanoseconds.toDouble())) 18 | 19 | public actual val seconds: Long = nativeValue.seconds.toLong() 20 | public actual val nanoseconds: Int = nativeValue.nanoseconds.toInt() 21 | 22 | override fun equals(other: Any?): Boolean = 23 | this === other || other is Timestamp && nativeValue.isEqual(other.nativeValue) 24 | override fun hashCode(): Int = nativeValue.toMillis().hashCode() 25 | override fun toString(): String = nativeValue.toString() 26 | 27 | public actual companion object { 28 | public actual fun now(): Timestamp = Timestamp(NativeTimestamp.now()) 29 | } 30 | 31 | /** A server time timestamp. */ 32 | @Serializable(with = ServerTimestampSerializer::class) 33 | public actual object ServerTimestamp : BaseTimestamp() 34 | } 35 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/_encoders.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | @PublishedApi 4 | internal actual fun isSpecialValue(value: Any): Boolean = when (value) { 5 | is NativeFieldValue, 6 | is NativeGeoPoint, 7 | is NativeTimestamp, 8 | is NativeDocumentReferenceType, 9 | -> true 10 | else -> false 11 | } 12 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeCollectionReferenceWrapper.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import dev.gitlive.firebase.firestore.NativeCollectionReference 4 | import dev.gitlive.firebase.firestore.externals.CollectionReference 5 | import dev.gitlive.firebase.firestore.externals.addDoc 6 | import dev.gitlive.firebase.firestore.externals.doc 7 | import dev.gitlive.firebase.firestore.rethrow 8 | import dev.gitlive.firebase.internal.EncodedObject 9 | import dev.gitlive.firebase.internal.js 10 | import kotlinx.coroutines.await 11 | 12 | internal actual class NativeCollectionReferenceWrapper internal actual constructor(actual override val native: NativeCollectionReference) : NativeQueryWrapper(native) { 13 | 14 | constructor(js: CollectionReference) : this(NativeCollectionReference(js)) 15 | 16 | override val js: CollectionReference = native.js 17 | 18 | actual val path: String 19 | get() = rethrow { js.path } 20 | 21 | actual val document get() = rethrow { NativeDocumentReference(doc(js)) } 22 | 23 | actual val parent get() = rethrow { js.parent?.let { NativeDocumentReference(it) } } 24 | 25 | actual fun document(documentPath: String) = rethrow { 26 | NativeDocumentReference( 27 | doc( 28 | js, 29 | documentPath, 30 | ), 31 | ) 32 | } 33 | 34 | actual suspend fun addEncoded(data: EncodedObject) = rethrow { 35 | NativeDocumentReference(addDoc(js, data.js).await()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/SetOptions.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore.internal 2 | 3 | import kotlin.js.Json 4 | import kotlin.js.json 5 | 6 | internal val SetOptions.js: Json 7 | get() = when (this) { 8 | is SetOptions.Merge -> json("merge" to true) 9 | is SetOptions.Overwrite -> json("merge" to false) 10 | is SetOptions.MergeFields -> json("mergeFields" to fields.toTypedArray()) 11 | is SetOptions.MergeFieldPaths -> json("mergeFields" to encodedFieldPaths.toTypedArray()) 12 | } 13 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import kotlin.test.Ignore 4 | 5 | actual typealias IgnoreJs = Ignore 6 | 7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 8 | actual annotation class IgnoreForAndroidUnitTest 9 | -------------------------------------------------------------------------------- /firebase-firestore/src/jsTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.firestore 6 | 7 | import kotlin.js.json 8 | 9 | actual val emulatorHost: String = "localhost" 10 | 11 | actual val context: Any = Unit 12 | 13 | actual fun encodedAsMap(encoded: Any?): Map = (js("Object").entries(encoded) as Array>).associate { 14 | it[0] as String to it[1] 15 | } 16 | actual fun Map.asEncoded(): Any = 17 | json(*entries.map { (key, value) -> key to value }.toTypedArray()) 18 | -------------------------------------------------------------------------------- /firebase-firestore/src/jvmTest/kotlin/dev/gitlive/firebase/firestore/Ignore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 4 | actual annotation class IgnoreJs 5 | 6 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 7 | actual annotation class IgnoreForAndroidUnitTest 8 | -------------------------------------------------------------------------------- /firebase-firestore/src/jvmTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.firestore 2 | 3 | import dev.gitlive.firebase.testContext 4 | 5 | actual val emulatorHost: String = "localhost" 6 | 7 | actual val context: Any = testContext 8 | 9 | @Suppress("UNCHECKED_CAST") 10 | actual fun encodedAsMap(encoded: Any?): Map = encoded as Map 11 | actual fun Map.asEncoded(): Any = this 12 | -------------------------------------------------------------------------------- /firebase-functions/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-functions 2 | This module is a direct forward of the Firebase Functions library. It provides the main functionality, like calling Firebase Remote Fuctions. -------------------------------------------------------------------------------- /firebase-functions/firebase_functions.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_functions' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_functions.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-functions', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_functions', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_functions', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-functions", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-functions.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-functions/src/jsMain/kotlin/dev/gitlive/firebase/functions/externals/HttpsCallableExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.functions.externals 6 | 7 | import kotlin.js.Promise 8 | 9 | public operator fun HttpsCallable.invoke(): Promise = asDynamic()() as Promise 10 | public operator fun HttpsCallable.invoke(data: Any?): Promise = asDynamic()(data) as Promise 11 | -------------------------------------------------------------------------------- /firebase-functions/src/jsMain/kotlin/dev/gitlive/firebase/functions/externals/functions.kt: -------------------------------------------------------------------------------- 1 | @file:JsModule("firebase/functions") 2 | @file:JsNonModule 3 | 4 | package dev.gitlive.firebase.functions.externals 5 | 6 | import dev.gitlive.firebase.externals.FirebaseApp 7 | import kotlin.js.Json 8 | 9 | public external fun connectFunctionsEmulator(functions: Functions, host: String, port: Int) 10 | 11 | public external fun getFunctions( 12 | app: FirebaseApp? = definedExternally, 13 | regionOrCustomDomain: String? = definedExternally, 14 | ): Functions 15 | 16 | public external fun httpsCallable(functions: Functions, name: String, options: Json?): HttpsCallable 17 | 18 | public external interface Functions 19 | 20 | public external interface HttpsCallableResult { 21 | public val data: Any? 22 | } 23 | 24 | public external interface HttpsCallable 25 | -------------------------------------------------------------------------------- /firebase-installations/api/android/firebase-installations.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/installations/FirebaseInstallations { 2 | public final fun delete (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 3 | public final fun getId (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 4 | public final fun getToken (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; 5 | } 6 | 7 | public final class dev/gitlive/firebase/installations/InstallationsKt { 8 | public static final fun getAndroid (Ldev/gitlive/firebase/installations/FirebaseInstallations;)Lcom/google/firebase/installations/FirebaseInstallations; 9 | public static final fun getInstallations (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/installations/FirebaseInstallations; 10 | public static final fun installations (Ldev/gitlive/firebase/Firebase;Ldev/gitlive/firebase/FirebaseApp;)Ldev/gitlive/firebase/installations/FirebaseInstallations; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /firebase-installations/api/jvm/firebase-installations.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/installations/FirebaseInstallations { 2 | public final fun delete (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 3 | public final fun getId (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 4 | public final fun getToken (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; 5 | } 6 | 7 | public final class dev/gitlive/firebase/installations/InstallationsKt { 8 | public static final fun getAndroid (Ldev/gitlive/firebase/installations/FirebaseInstallations;)Lcom/google/firebase/installations/FirebaseInstallations; 9 | public static final fun getInstallations (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/installations/FirebaseInstallations; 10 | public static final fun installations (Ldev/gitlive/firebase/Firebase;Ldev/gitlive/firebase/FirebaseApp;)Ldev/gitlive/firebase/installations/FirebaseInstallations; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /firebase-installations/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-installations 2 | This module is a direct forward of the Firebase Installations library. It provides the main functionality, like getting an installation ID. -------------------------------------------------------------------------------- /firebase-installations/firebase_installations.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_installations' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_installations.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-installations', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_installations', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_installations', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-installations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-installations", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-installations.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-installations/src/androidMain/kotlin/dev/gitlive/firebase/installations/installations.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.installations 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.android 6 | import kotlinx.coroutines.tasks.await 7 | 8 | public val FirebaseInstallations.android: com.google.firebase.installations.FirebaseInstallations get() = com.google.firebase.installations.FirebaseInstallations.getInstance() 9 | 10 | public actual val Firebase.installations: FirebaseInstallations 11 | get() = FirebaseInstallations(com.google.firebase.installations.FirebaseInstallations.getInstance()) 12 | 13 | public actual fun Firebase.installations(app: FirebaseApp): FirebaseInstallations = FirebaseInstallations(com.google.firebase.installations.FirebaseInstallations.getInstance(app.android)) 14 | 15 | public actual class FirebaseInstallations internal constructor(internal val android: com.google.firebase.installations.FirebaseInstallations) { 16 | 17 | public actual suspend fun delete(): Unit = android.delete().await().let { } 18 | 19 | public actual suspend fun getId(): String = android.id.await() 20 | 21 | public actual suspend fun getToken(forceRefresh: Boolean): String = 22 | android.getToken(forceRefresh).await().token 23 | } 24 | 25 | public actual typealias FirebaseInstallationsException = com.google.firebase.installations.FirebaseInstallationsException 26 | -------------------------------------------------------------------------------- /firebase-installations/src/jsMain/kotlin/dev/gitlive/firebase/installations/externals/installations.kt: -------------------------------------------------------------------------------- 1 | @file:JsModule("firebase/installations") 2 | @file:JsNonModule 3 | 4 | package dev.gitlive.firebase.installations.externals 5 | 6 | import dev.gitlive.firebase.externals.FirebaseApp 7 | import kotlin.js.Promise 8 | 9 | public external fun delete(installations: Installations): Promise 10 | 11 | public external fun getId(installations: Installations): Promise 12 | 13 | public external fun getInstallations(app: FirebaseApp? = definedExternally): Installations 14 | 15 | public external fun getToken(installations: Installations, forceRefresh: Boolean): Promise 16 | 17 | public external interface Installations 18 | -------------------------------------------------------------------------------- /firebase-installations/src/jsMain/kotlin/dev/gitlive/firebase/installations/installations.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.installations 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.FirebaseException 6 | import dev.gitlive.firebase.installations.externals.* 7 | import dev.gitlive.firebase.js 8 | import kotlinx.coroutines.await 9 | 10 | public actual val Firebase.installations: FirebaseInstallations 11 | get() = rethrow { FirebaseInstallations(getInstallations()) } 12 | 13 | public actual fun Firebase.installations(app: FirebaseApp): FirebaseInstallations = 14 | rethrow { FirebaseInstallations(getInstallations(app.js)) } 15 | 16 | public val FirebaseInstallations.js get() = js 17 | 18 | public actual class FirebaseInstallations internal constructor(internal val js: Installations) { 19 | 20 | public actual suspend fun delete(): Unit = rethrow { delete(js).await() } 21 | 22 | public actual suspend fun getId(): String = rethrow { getId(js).await() } 23 | 24 | public actual suspend fun getToken(forceRefresh: Boolean): String = 25 | rethrow { getToken(js, forceRefresh).await() } 26 | } 27 | 28 | public actual open class FirebaseInstallationsException(code: String?, cause: Throwable) : FirebaseException(code, cause) 29 | 30 | internal inline fun T.rethrow(function: T.() -> R): R = dev.gitlive.firebase.installations.rethrow { function() } 31 | 32 | internal inline fun rethrow(function: () -> R): R { 33 | try { 34 | return function() 35 | } catch (e: Exception) { 36 | throw e 37 | } catch (e: dynamic) { 38 | throw FirebaseInstallationsException(e.code.unsafeCast(), e.unsafeCast()) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /firebase-messaging/api/android/firebase-messaging.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/messaging/FirebaseMessaging { 2 | public fun (Lcom/google/firebase/messaging/FirebaseMessaging;)V 3 | public final fun deleteToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 4 | public final fun getToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 5 | public final fun subscribeToTopic (Ljava/lang/String;)V 6 | public final fun unsubscribeFromTopic (Ljava/lang/String;)V 7 | } 8 | 9 | public final class dev/gitlive/firebase/messaging/android { 10 | public static final fun getAndroid (Ldev/gitlive/firebase/messaging/FirebaseMessaging;)Lcom/google/firebase/messaging/FirebaseMessaging; 11 | public static final fun getMessaging (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/messaging/FirebaseMessaging; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /firebase-messaging/api/jvm/firebase-messaging.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/messaging/FirebaseMessaging { 2 | public fun ()V 3 | public final fun deleteToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 4 | public final fun getToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 5 | public final fun subscribeToTopic (Ljava/lang/String;)V 6 | public final fun unsubscribeFromTopic (Ljava/lang/String;)V 7 | } 8 | 9 | public final class dev/gitlive/firebase/messaging/android { 10 | public static final fun getMessaging (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/messaging/FirebaseMessaging; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /firebase-messaging/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-messaging 2 | This module is a direct forward of the Firebase Messaging library. It provides the main functionality, like subscribing to topics. -------------------------------------------------------------------------------- /firebase-messaging/firebase_messaging.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_messaging' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_messaging.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-messaging', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_messaging', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_messaging', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end -------------------------------------------------------------------------------- /firebase-messaging/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-messaging", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-messaging.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.8.20", 29 | "kotlinx-coroutines-core": "1.6.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-messaging/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import dev.gitlive.firebase.Firebase 5 | import dev.gitlive.firebase.FirebaseOptions 6 | import dev.gitlive.firebase.apps 7 | import dev.gitlive.firebase.initialize 8 | import kotlin.test.BeforeTest 9 | 10 | class AndroidInstrumentedFirebaseMessagingTest : FirebaseMessagingTest() { 11 | 12 | private val context = InstrumentationRegistry.getInstrumentation().context 13 | 14 | @BeforeTest 15 | fun initializeFirebase() { 16 | Firebase.apps(context).firstOrNull() ?: Firebase.initialize( 17 | context, 18 | FirebaseOptions( 19 | applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a", 20 | apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0", 21 | databaseUrl = "https://fir-kotlin-sdk.firebaseio.com", 22 | storageBucket = "fir-kotlin-sdk.appspot.com", 23 | projectId = "fir-kotlin-sdk", 24 | gcmSenderId = "846484016111", 25 | ), 26 | ) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /firebase-messaging/src/androidMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("android") 2 | 3 | package dev.gitlive.firebase.messaging 4 | 5 | import dev.gitlive.firebase.Firebase 6 | import kotlinx.coroutines.tasks.await 7 | 8 | public val FirebaseMessaging.android: com.google.firebase.messaging.FirebaseMessaging get() = com.google.firebase.messaging.FirebaseMessaging.getInstance() 9 | 10 | public actual val Firebase.messaging: FirebaseMessaging 11 | get() = FirebaseMessaging(com.google.firebase.messaging.FirebaseMessaging.getInstance()) 12 | 13 | public actual class FirebaseMessaging(internal val android: com.google.firebase.messaging.FirebaseMessaging) { 14 | public actual fun subscribeToTopic(topic: String) { 15 | android.subscribeToTopic(topic) 16 | } 17 | 18 | public actual fun unsubscribeFromTopic(topic: String) { 19 | android.unsubscribeFromTopic(topic) 20 | } 21 | 22 | public actual suspend fun getToken(): String = android.token.await() 23 | 24 | public actual suspend fun deleteToken() { 25 | android.deleteToken().await() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | 6 | /** Returns the [FirebaseMessaging] instance of the default [FirebaseApp]. */ 7 | public expect val Firebase.messaging: FirebaseMessaging 8 | 9 | /** 10 | * Top level [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/) 11 | * singleton that provides methods for subscribing to topics and sending upstream messages. 12 | */ 13 | public expect class FirebaseMessaging { 14 | /** 15 | * Subscribe to a topic. 16 | * @param topic The topic to subscribe to. 17 | */ 18 | public fun subscribeToTopic(topic: String) 19 | 20 | /** 21 | * Unsubscribe from a topic. 22 | * @param topic The topic to unsubscribe from. 23 | */ 24 | public fun unsubscribeFromTopic(topic: String) 25 | 26 | /** 27 | * Get FCM token for client 28 | * @return [String] FCM token 29 | */ 30 | public suspend fun getToken(): String 31 | 32 | /** 33 | * Delete FCM token for client 34 | */ 35 | public suspend fun deleteToken() 36 | } 37 | -------------------------------------------------------------------------------- /firebase-messaging/src/commonTest/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import kotlin.test.Test 5 | import kotlin.test.assertNotNull 6 | 7 | abstract class FirebaseMessagingTest { 8 | 9 | @Test 10 | fun initialization() { 11 | assertNotNull(Firebase.messaging) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /firebase-messaging/src/iosMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | import cocoapods.FirebaseMessaging.FIRMessaging 4 | import dev.gitlive.firebase.Firebase 5 | import kotlinx.coroutines.CompletableDeferred 6 | import platform.Foundation.NSError 7 | 8 | public val FirebaseMessaging.ios: FIRMessaging get() = FIRMessaging.messaging() 9 | 10 | public actual val Firebase.messaging: FirebaseMessaging 11 | get() = FirebaseMessaging(FIRMessaging.messaging()) 12 | 13 | public actual class FirebaseMessaging(internal val ios: FIRMessaging) { 14 | public actual fun subscribeToTopic(topic: String) { 15 | ios.subscribeToTopic(topic) 16 | } 17 | 18 | public actual fun unsubscribeFromTopic(topic: String) { 19 | ios.unsubscribeFromTopic(topic) 20 | } 21 | 22 | public actual suspend fun getToken(): String = awaitResult { ios.tokenWithCompletion(it) } 23 | 24 | public actual suspend fun deleteToken() { 25 | await { ios.deleteTokenWithCompletion(it) } 26 | } 27 | } 28 | 29 | public suspend inline fun T.await(function: T.(callback: (NSError?) -> Unit) -> Unit) { 30 | val job = CompletableDeferred() 31 | function { error -> 32 | if (error == null) { 33 | job.complete(Unit) 34 | } else { 35 | job.completeExceptionally(Exception(error.toString())) 36 | } 37 | } 38 | job.await() 39 | } 40 | 41 | public suspend inline fun T.awaitResult(function: T.(callback: (R?, NSError?) -> Unit) -> Unit): R { 42 | val job = CompletableDeferred() 43 | function { result, error -> 44 | if (error == null) { 45 | job.complete(result) 46 | } else { 47 | job.completeExceptionally(Exception(error.toString())) 48 | } 49 | } 50 | return job.await() as R 51 | } 52 | -------------------------------------------------------------------------------- /firebase-messaging/src/iosTest/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | class IOSFirebaseMessagingTest : FirebaseMessagingTest() 4 | -------------------------------------------------------------------------------- /firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/externals/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging.externals 2 | 3 | import dev.gitlive.firebase.externals.FirebaseApp 4 | import kotlin.js.Promise 5 | 6 | public external fun getMessaging( 7 | app: FirebaseApp? = definedExternally, 8 | ): Messaging 9 | 10 | public external fun getToken(messaging: Messaging = definedExternally, options: dynamic = definedExternally): Promise 11 | 12 | public external fun deleteToken(messaging: Messaging = definedExternally): Promise 13 | 14 | public external interface Messaging 15 | -------------------------------------------------------------------------------- /firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.messaging 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.messaging.externals.Messaging 5 | import dev.gitlive.firebase.messaging.externals.getMessaging 6 | import kotlinx.coroutines.await 7 | 8 | public actual val Firebase.messaging: FirebaseMessaging 9 | get() = FirebaseMessaging(getMessaging()) 10 | 11 | public val FirebaseMessaging.js: Messaging get() = js 12 | 13 | public actual class FirebaseMessaging(internal val js: Messaging) { 14 | public actual fun subscribeToTopic(topic: String) { 15 | // This is not supported in the JS SDK 16 | // https://firebase.google.com/docs/reference/js/messaging_.md#@firebase/messaging 17 | throw NotImplementedError("Subscribing to topics is not supported in the JS SDK") 18 | } 19 | 20 | public actual fun unsubscribeFromTopic(topic: String) { 21 | // This is not supported in the JS SDK 22 | // https://firebase.google.com/docs/reference/js/messaging_.md#@firebase/messaging 23 | throw NotImplementedError("Unsubscribing from topics is not supported in the JS SDK") 24 | } 25 | 26 | public actual suspend fun getToken(): String = dev.gitlive.firebase.messaging.externals.getToken(js).await() 27 | 28 | public actual suspend fun deleteToken() { 29 | dev.gitlive.firebase.messaging.externals.deleteToken(js).await() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-messaging/src/jvmMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("android") 2 | 3 | package dev.gitlive.firebase.messaging 4 | 5 | import dev.gitlive.firebase.Firebase 6 | 7 | public actual val Firebase.messaging: FirebaseMessaging 8 | get() = TODO("Not yet implemented") 9 | 10 | public actual class FirebaseMessaging { 11 | public actual fun subscribeToTopic(topic: String) { 12 | TODO("Not yet implemented") 13 | } 14 | 15 | public actual fun unsubscribeFromTopic(topic: String) { 16 | TODO("Not yet implemented") 17 | } 18 | 19 | public actual suspend fun getToken(): String { 20 | TODO("Not yet implemented") 21 | } 22 | 23 | public actual suspend fun deleteToken() { 24 | TODO("Not yet implemented") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /firebase-perf/api/jvm/firebase-perf.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/perf/FirebasePerformance { 2 | public fun ()V 3 | public final fun isPerformanceCollectionEnabled ()Z 4 | public final fun newTrace (Ljava/lang/String;)Ldev/gitlive/firebase/perf/metrics/Trace; 5 | public final fun setPerformanceCollectionEnabled (Z)V 6 | } 7 | 8 | public class dev/gitlive/firebase/perf/FirebasePerformanceException : com/google/firebase/FirebaseException { 9 | } 10 | 11 | public final class dev/gitlive/firebase/perf/Performance_jvmKt { 12 | public static final fun getPerformance (Ldev/gitlive/firebase/Firebase;)Ldev/gitlive/firebase/perf/FirebasePerformance; 13 | public static final fun performance (Ldev/gitlive/firebase/Firebase;Ldev/gitlive/firebase/FirebaseApp;)Ldev/gitlive/firebase/perf/FirebasePerformance; 14 | } 15 | 16 | public final class dev/gitlive/firebase/perf/metrics/Trace { 17 | public fun ()V 18 | public final fun getLongMetric (Ljava/lang/String;)J 19 | public final fun incrementMetric (Ljava/lang/String;J)V 20 | public final fun putMetric (Ljava/lang/String;J)V 21 | public final fun start ()V 22 | public final fun stop ()V 23 | } 24 | 25 | -------------------------------------------------------------------------------- /firebase-perf/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-perf 2 | This module is a direct forward of the Firebase Performance library. It provides the main functionality, like tracking performance. -------------------------------------------------------------------------------- /firebase-perf/firebase_perf.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_perf' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_perf.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-perf', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_perf', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_perf', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end 40 | -------------------------------------------------------------------------------- /firebase-perf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-perf", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-perf.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.6.10", 29 | "kotlinx-coroutines-core": "1.6.1-native-mt" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-perf/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-perf/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.perf 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-perf/src/androidMain/kotlin/dev/gitlive/firebase/perf/metrics/Trace.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf.metrics 2 | 3 | import com.google.firebase.perf.metrics.Trace as AndroidTrace 4 | import dev.gitlive.firebase.perf.session.PerfSession 5 | 6 | public val Trace.android: AndroidTrace get() = android 7 | 8 | public actual class Trace internal constructor(internal val android: AndroidTrace) { 9 | 10 | public actual fun start() { 11 | android.start() 12 | } 13 | 14 | public actual fun stop() { 15 | android.stop() 16 | } 17 | 18 | public actual fun getLongMetric(metricName: String): Long = android.getLongMetric(metricName) 19 | 20 | public actual fun incrementMetric(metricName: String, incrementBy: Long) { 21 | android.incrementMetric(metricName, incrementBy) 22 | } 23 | 24 | public actual fun putMetric(metricName: String, value: Long) { 25 | android.putMetric(metricName, value) 26 | } 27 | 28 | public fun getAttributes(): Map = android.attributes 29 | 30 | public fun getAttribute(attribute: String): String? = android.getAttribute(attribute) 31 | 32 | public fun putAttribute(attribute: String, value: String) { 33 | android.putAttribute(attribute, value) 34 | } 35 | 36 | public fun removeAttribute(attribute: String) { 37 | android.removeAttribute(attribute) 38 | } 39 | 40 | public fun updateSession(session: PerfSession) { 41 | android.updateSession(session.android) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /firebase-perf/src/androidMain/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.android as publicAndroid 6 | import dev.gitlive.firebase.perf.metrics.Trace 7 | 8 | public val FirebasePerformance.android: com.google.firebase.perf.FirebasePerformance get() = com.google.firebase.perf.FirebasePerformance.getInstance() 9 | 10 | public actual val Firebase.performance: FirebasePerformance get() = 11 | FirebasePerformance(com.google.firebase.perf.FirebasePerformance.getInstance()) 12 | 13 | public actual fun Firebase.performance(app: FirebaseApp): FirebasePerformance = 14 | FirebasePerformance(app.publicAndroid.get(com.google.firebase.perf.FirebasePerformance::class.java)) 15 | 16 | public actual class FirebasePerformance(internal val android: com.google.firebase.perf.FirebasePerformance) { 17 | 18 | public actual fun newTrace(traceName: String): Trace = Trace(android.newTrace(traceName)) 19 | 20 | public actual fun isPerformanceCollectionEnabled(): Boolean = android.isPerformanceCollectionEnabled 21 | 22 | public actual fun setPerformanceCollectionEnabled(enable: Boolean) { 23 | android.isPerformanceCollectionEnabled = enable 24 | } 25 | } 26 | 27 | public actual open class FirebasePerformanceException(message: String) : com.google.firebase.FirebaseException(message) 28 | -------------------------------------------------------------------------------- /firebase-perf/src/androidMain/kotlin/dev/gitlive/firebase/perf/session/PerfSession.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf.session 2 | 3 | import com.google.firebase.perf.session.PerfSession as AndroidPerfSession 4 | 5 | public val PerfSession.android: AndroidPerfSession get() = android 6 | 7 | public class PerfSession internal constructor(internal val android: AndroidPerfSession) 8 | -------------------------------------------------------------------------------- /firebase-perf/src/androidUnitTest/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.perf 8 | 9 | import org.junit.Ignore 10 | 11 | actual val context: Any = "" 12 | 13 | actual typealias IgnoreForAndroidUnitTest = Ignore 14 | -------------------------------------------------------------------------------- /firebase-perf/src/iosMain/kotlin/dev/gitlive/firebase/perf/metrics/Trace.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf.metrics 2 | 3 | import cocoapods.FirebasePerformance.FIRTrace 4 | 5 | public val Trace.ios: FIRTrace? get() = ios 6 | 7 | public actual class Trace internal constructor(internal val ios: FIRTrace?) { 8 | 9 | public actual fun start() { 10 | ios?.start() 11 | } 12 | 13 | public actual fun stop() { 14 | ios?.stop() 15 | } 16 | 17 | public actual fun getLongMetric(metricName: String): Long = ios?.valueForIntMetric(metricName) ?: 0L 18 | 19 | public actual fun incrementMetric(metricName: String, incrementBy: Long) { 20 | ios?.incrementMetric(metricName, incrementBy) 21 | } 22 | 23 | public actual fun putMetric(metricName: String, value: Long) { 24 | ios?.setIntValue(value, metricName) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /firebase-perf/src/iosMain/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf 2 | 3 | import cocoapods.FirebasePerformance.FIRPerformance 4 | import dev.gitlive.firebase.Firebase 5 | import dev.gitlive.firebase.FirebaseApp 6 | import dev.gitlive.firebase.FirebaseException 7 | import dev.gitlive.firebase.perf.metrics.Trace 8 | 9 | public val FirebasePerformance.ios: FIRPerformance get() = FIRPerformance.sharedInstance() 10 | 11 | public actual val Firebase.performance: FirebasePerformance get() = 12 | FirebasePerformance(FIRPerformance.sharedInstance()) 13 | 14 | public actual fun Firebase.performance(app: FirebaseApp): FirebasePerformance = 15 | FirebasePerformance(FIRPerformance.sharedInstance()) 16 | 17 | public actual class FirebasePerformance(internal val ios: FIRPerformance) { 18 | 19 | public actual fun newTrace(traceName: String): Trace = Trace(ios.traceWithName(traceName)) 20 | 21 | public actual fun isPerformanceCollectionEnabled(): Boolean = ios.isDataCollectionEnabled() 22 | 23 | public actual fun setPerformanceCollectionEnabled(enable: Boolean) { 24 | ios.dataCollectionEnabled = enable 25 | } 26 | } 27 | 28 | public actual open class FirebasePerformanceException(message: String) : FirebaseException(message) 29 | -------------------------------------------------------------------------------- /firebase-perf/src/iosTest/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.perf 6 | 7 | actual val context: Any = Unit 8 | 9 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 10 | actual annotation class IgnoreForAndroidUnitTest 11 | -------------------------------------------------------------------------------- /firebase-perf/src/jsMain/kotlin/dev/gitlive/firebase/perf/externals/performance.kt: -------------------------------------------------------------------------------- 1 | @file:JsModule("firebase/performance") 2 | @file:JsNonModule 3 | 4 | package dev.gitlive.firebase.perf.externals 5 | 6 | import dev.gitlive.firebase.externals.FirebaseApp 7 | 8 | public external fun getPerformance(app: FirebaseApp? = definedExternally): FirebasePerformance 9 | 10 | public external fun trace(performance: FirebasePerformance, name: String): PerformanceTrace 11 | 12 | public external interface FirebasePerformance { 13 | public var dataCollectionEnabled: Boolean 14 | public var instrumentationEnabled: Boolean 15 | } 16 | 17 | public external interface PerformanceTrace { 18 | public fun getAttribute(attr: String): String? 19 | public fun getAttributes(): Map 20 | public fun getMetric(metricName: String): Int 21 | public fun incrementMetric(metricName: String, num: Int? = definedExternally) 22 | public fun putAttribute(attr: String, value: String) 23 | public fun putMetric(metricName: String, num: Int) 24 | public fun removeAttribute(attr: String) 25 | public fun start() 26 | public fun stop() 27 | } 28 | -------------------------------------------------------------------------------- /firebase-perf/src/jsMain/kotlin/dev/gitlive/firebase/perf/metrics/Trace.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf.metrics 2 | 3 | import dev.gitlive.firebase.perf.externals.PerformanceTrace 4 | import dev.gitlive.firebase.perf.rethrow 5 | 6 | public val Trace.js get() = js 7 | 8 | public actual class Trace internal constructor(internal val js: PerformanceTrace) { 9 | 10 | public actual fun start(): Unit = rethrow { js.start() } 11 | public actual fun stop(): Unit = rethrow { js.stop() } 12 | public actual fun getLongMetric(metricName: String): Long = rethrow { js.getMetric(metricName).toLong() } 13 | public actual fun incrementMetric(metricName: String, incrementBy: Long): Unit = rethrow { js.incrementMetric(metricName, incrementBy.toInt()) } 14 | public actual fun putMetric(metricName: String, value: Long): Unit = rethrow { js.putMetric(metricName, value.toInt()) } 15 | public fun getAttribute(attribute: String): String? = rethrow { js.getAttribute(attribute) } 16 | public fun putAttribute(attribute: String, value: String): Unit = rethrow { js.putAttribute(attribute, value) } 17 | public fun removeAttribute(attribute: String): Unit = rethrow { js.removeAttribute(attribute) } 18 | } 19 | -------------------------------------------------------------------------------- /firebase-perf/src/jsTest/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.perf 6 | 7 | import dev.gitlive.firebase.Firebase 8 | import dev.gitlive.firebase.FirebaseOptions 9 | import dev.gitlive.firebase.apps 10 | import dev.gitlive.firebase.initialize 11 | import dev.gitlive.firebase.runTest 12 | import kotlin.test.* 13 | 14 | actual val context: Any = Unit 15 | 16 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 17 | actual annotation class IgnoreForAndroidUnitTest 18 | 19 | class JsPerformanceTest { 20 | 21 | private lateinit var performance: FirebasePerformance 22 | 23 | @BeforeTest 24 | fun initializeFirebase() { 25 | val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize( 26 | context, 27 | FirebaseOptions( 28 | applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a", 29 | apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0", 30 | databaseUrl = "https://fir-kotlin-sdk.firebaseio.com", 31 | storageBucket = "fir-kotlin-sdk.appspot.com", 32 | projectId = "fir-kotlin-sdk", 33 | gcmSenderId = "846484016111", 34 | ), 35 | ) 36 | 37 | performance = Firebase.performance(app) 38 | } 39 | 40 | @Test 41 | fun testInstrumentationEnabled() = runTest { 42 | performance.setInstrumentationEnabled(false) 43 | 44 | assertFalse(performance.isInstrumentationEnabled()) 45 | 46 | performance.setInstrumentationEnabled(true) 47 | 48 | assertTrue(performance.isInstrumentationEnabled()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /firebase-perf/src/jvmMain/kotlin/dev/gitlive/firebase/perf/metrics/Trace.jvm.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf.metrics 2 | 3 | public actual class Trace { 4 | public actual fun start() { 5 | } 6 | 7 | public actual fun stop() { 8 | } 9 | 10 | public actual fun getLongMetric(metricName: String): Long { 11 | TODO("Not yet implemented") 12 | } 13 | 14 | public actual fun incrementMetric(metricName: String, incrementBy: Long) { 15 | } 16 | 17 | public actual fun putMetric(metricName: String, value: Long) { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-perf/src/jvmMain/kotlin/dev/gitlive/firebase/perf/performance.jvm.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.perf 2 | 3 | import dev.gitlive.firebase.Firebase 4 | import dev.gitlive.firebase.FirebaseApp 5 | import dev.gitlive.firebase.FirebaseException 6 | import dev.gitlive.firebase.perf.metrics.Trace 7 | 8 | /** Returns the [FirebasePerformance] instance of the default [FirebaseApp]. */ 9 | public actual val Firebase.performance: FirebasePerformance 10 | get() = TODO("Not yet implemented") 11 | 12 | /** Returns the [FirebasePerformance] instance of a given [FirebaseApp]. */ 13 | public actual fun Firebase.performance(app: FirebaseApp): FirebasePerformance { 14 | TODO("Not yet implemented") 15 | } 16 | 17 | public actual class FirebasePerformance { 18 | public actual fun newTrace(traceName: String): Trace { 19 | TODO("Not yet implemented") 20 | } 21 | 22 | public actual fun isPerformanceCollectionEnabled(): Boolean { 23 | TODO("Not yet implemented") 24 | } 25 | 26 | public actual fun setPerformanceCollectionEnabled(enable: Boolean) { 27 | } 28 | } 29 | 30 | public actual open class FirebasePerformanceException internal constructor(message: String) : FirebaseException(message) 31 | -------------------------------------------------------------------------------- /firebase-perf/src/jvmTest/kotlin/dev/gitlive/firebase/perf/performance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.perf 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val context: Any = testContext 12 | 13 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 14 | actual annotation class IgnoreForAndroidUnitTest 15 | -------------------------------------------------------------------------------- /firebase-storage/documentation.md: -------------------------------------------------------------------------------- 1 | # Module firebase-storage 2 | This module is a direct forward of the Firebase Storage library. It provides the main functionality, like storing files. -------------------------------------------------------------------------------- /firebase-storage/firebase_storage.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'firebase_storage' 3 | spec.version = '1.8.1' 4 | spec.homepage = '' 5 | spec.source = { :http=> ''} 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = '' 9 | spec.vendored_frameworks = 'build/cocoapods/framework/firebase_storage.framework' 10 | spec.libraries = 'c++' 11 | 12 | 13 | 14 | spec.pod_target_xcconfig = { 15 | 'KOTLIN_PROJECT_PATH' => ':firebase-storage', 16 | 'PRODUCT_MODULE_NAME' => 'firebase_storage', 17 | } 18 | 19 | spec.script_phases = [ 20 | { 21 | :name => 'Build firebase_storage', 22 | :execution_position => :before_compile, 23 | :shell_path => '/bin/sh', 24 | :script => <<-SCRIPT 25 | if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then 26 | echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" 27 | exit 0 28 | fi 29 | set -ev 30 | REPO_ROOT="$PODS_TARGET_SRCROOT" 31 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ 32 | -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ 33 | -Pkotlin.native.cocoapods.archs="$ARCHS" \ 34 | -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" 35 | SCRIPT 36 | } 37 | ] 38 | 39 | end -------------------------------------------------------------------------------- /firebase-storage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitlive/firebase-storage", 3 | "version": "2.1.0", 4 | "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", 5 | "main": "firebase-storage.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/GitLiveApp/firebase-kotlin-sdk.git" 12 | }, 13 | "keywords": [ 14 | "kotlin", 15 | "multiplatform", 16 | "kotlin-js", 17 | "firebase" 18 | ], 19 | "author": "dev.gitlive", 20 | "license": "Apache-2.0", 21 | "bugs": { 22 | "url": "https://github.com/GitLiveApp/firebase-kotlin-sdk/issues" 23 | }, 24 | "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", 25 | "dependencies": { 26 | "@gitlive/firebase-app": "2.1.0", 27 | "firebase": "9.19.1", 28 | "kotlin": "1.6.10", 29 | "kotlinx-coroutines-core": "1.6.1-native-mt" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /firebase-storage/src/androidInstrumentedTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-storage/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/storage/storage.android.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | actual fun createTestData(): Data = Data("test".toByteArray()) 4 | -------------------------------------------------------------------------------- /firebase-storage/src/androidInstrumentedTest/kotlin/dev/gitlive/firebase/storage/storage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.storage 8 | 9 | import androidx.test.platform.app.InstrumentationRegistry 10 | 11 | actual val emulatorHost: String = "10.0.2.2" 12 | 13 | actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext 14 | 15 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 16 | actual annotation class IgnoreForAndroidUnitTest 17 | -------------------------------------------------------------------------------- /firebase-storage/src/androidUnitTest/kotlin/dev/gitlive/firebase/storage/storage.android.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | actual fun createTestData(): Data = Data("test".toByteArray()) 4 | -------------------------------------------------------------------------------- /firebase-storage/src/androidUnitTest/kotlin/dev/gitlive/firebase/storage/storage.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | import org.junit.Ignore 4 | 5 | actual val emulatorHost: String = "10.0.2.2" 6 | 7 | actual val context: Any = "" 8 | 9 | actual typealias IgnoreForAndroidUnitTest = Ignore 10 | -------------------------------------------------------------------------------- /firebase-storage/src/iosTest/kotlin/dev/gitlive/firebase/storage/storage.ios.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | import kotlinx.cinterop.BetaInteropApi 4 | import platform.Foundation.NSString 5 | import platform.Foundation.NSUTF8StringEncoding 6 | import platform.Foundation.create 7 | import platform.Foundation.dataUsingEncoding 8 | 9 | @OptIn(BetaInteropApi::class) 10 | actual fun createTestData(): Data { 11 | val value = NSString.create(string = "test") 12 | return Data(value.dataUsingEncoding(NSUTF8StringEncoding, false)!!) 13 | } 14 | -------------------------------------------------------------------------------- /firebase-storage/src/iosTest/kotlin/dev/gitlive/firebase/storage/storage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.storage 6 | 7 | actual val emulatorHost: String = "localhost" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | -------------------------------------------------------------------------------- /firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.js.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | import org.khronos.webgl.Uint8Array 4 | 5 | actual fun createTestData(): Data = Data(Uint8Array("test".encodeToByteArray().toTypedArray())) 6 | -------------------------------------------------------------------------------- /firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase.storage 6 | 7 | actual val emulatorHost: String = "127.0.0.1" 8 | 9 | actual val context: Any = Unit 10 | 11 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 12 | actual annotation class IgnoreForAndroidUnitTest 13 | -------------------------------------------------------------------------------- /firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt: -------------------------------------------------------------------------------- 1 | package dev.gitlive.firebase.storage 2 | 3 | actual fun createTestData(): Data { 4 | TODO("Not yet implemented") 5 | } 6 | -------------------------------------------------------------------------------- /firebase-storage/src/jvmTest/kotlin/dev/gitlive/firebase/storage/storage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | @file:JvmName("tests") 6 | 7 | package dev.gitlive.firebase.storage 8 | 9 | import dev.gitlive.firebase.testContext 10 | 11 | actual val emulatorHost: String = "localhost" 12 | 13 | actual val context: Any = testContext 14 | 15 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 16 | actual annotation class IgnoreForAndroidUnitTest 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GitLiveApp/firebase-kotlin-sdk/eafd4f4dc2a54d46bf9deafcb430387701889aab/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | include( 2 | "firebase-analytics", 3 | "firebase-app", 4 | "firebase-auth", 5 | "firebase-common", 6 | "firebase-common-internal", 7 | "firebase-config", 8 | "firebase-crashlytics", 9 | "firebase-database", 10 | "firebase-firestore", 11 | "firebase-functions", 12 | "firebase-installations", 13 | "firebase-messaging", 14 | "firebase-perf", 15 | "firebase-storage", 16 | "test-utils" 17 | ) 18 | 19 | pluginManagement { 20 | includeBuild("convention-plugin-test-option") 21 | repositories { 22 | google() 23 | mavenCentral() 24 | gradlePluginPortal() 25 | maven { url = uri("https://plugins.gradle.org/m2/") } 26 | } 27 | } 28 | 29 | dependencyResolutionManagement { 30 | repositories { 31 | mavenLocal() 32 | google() 33 | mavenCentral() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test-utils/api/android/test-utils.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/TestUtilsAndroid { 2 | public static final fun nativeAssertEquals (Ljava/lang/Object;Ljava/lang/Object;)V 3 | public static final fun nativeListOf ([Ljava/lang/Object;)Ljava/lang/Object; 4 | public static final fun nativeMapOf ([Lkotlin/Pair;)Ljava/lang/Object; 5 | public static final fun runBlockingTest (Lkotlin/jvm/functions/Function2;)V 6 | public static final fun runTest (Lkotlin/jvm/functions/Function2;)V 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test-utils/api/jvm/test-utils.api: -------------------------------------------------------------------------------- 1 | public final class dev/gitlive/firebase/TestUtilsJvm { 2 | public static final fun getTestContext ()Landroid/app/Application; 3 | public static final fun nativeAssertEquals (Ljava/lang/Object;Ljava/lang/Object;)V 4 | public static final fun nativeListOf ([Ljava/lang/Object;)Ljava/lang/Object; 5 | public static final fun nativeMapOf ([Lkotlin/Pair;)Ljava/lang/Object; 6 | public static final fun runBlockingTest (Lkotlin/jvm/functions/Function2;)V 7 | public static final fun runTest (Lkotlin/jvm/functions/Function2;)V 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test-utils/src/androidMain/kotlin/dev/gitlive/firebase/TestUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("TestUtilsAndroid") 2 | /* 3 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 4 | */ 5 | 6 | package dev.gitlive.firebase 7 | 8 | import kotlinx.coroutines.CoroutineScope 9 | import kotlinx.coroutines.runBlocking 10 | import kotlin.time.Duration.Companion.minutes 11 | 12 | actual fun runTest(test: suspend CoroutineScope.() -> Unit) = kotlinx.coroutines.test.runTest(timeout = 5.minutes) { test() } 13 | actual fun runBlockingTest(action: suspend CoroutineScope.() -> Unit) = runBlocking(block = action) 14 | 15 | actual fun nativeMapOf(vararg pairs: Pair): Any = mapOf(*pairs) 16 | actual fun nativeListOf(vararg elements: Any?): Any = listOf(*elements) 17 | actual fun nativeAssertEquals(expected: Any?, actual: Any?) { 18 | kotlin.test.assertEquals(expected, actual) 19 | } 20 | -------------------------------------------------------------------------------- /test-utils/src/commonMain/kotlin/dev/gitlive/firebase/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | import kotlinx.coroutines.CoroutineScope 8 | import kotlinx.coroutines.test.TestResult 9 | 10 | expect fun runTest(test: suspend CoroutineScope.() -> Unit): TestResult 11 | expect fun runBlockingTest(action: suspend CoroutineScope.() -> Unit) 12 | 13 | expect fun nativeMapOf(vararg pairs: Pair): Any 14 | expect fun nativeListOf(vararg elements: Any?): Any 15 | expect fun nativeAssertEquals(expected: Any?, actual: Any?) 16 | -------------------------------------------------------------------------------- /test-utils/src/iosMain/kotlin/dev/gitlive/firebase/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | import kotlinx.coroutines.CoroutineScope 8 | import kotlinx.coroutines.MainScope 9 | import kotlinx.coroutines.async 10 | import kotlinx.coroutines.runBlocking 11 | import kotlinx.coroutines.yield 12 | import platform.Foundation.NSDate 13 | import platform.Foundation.NSDefaultRunLoopMode 14 | import platform.Foundation.NSRunLoop 15 | import platform.Foundation.create 16 | import platform.Foundation.runMode 17 | 18 | actual fun runTest(test: suspend CoroutineScope.() -> Unit) = runBlocking { 19 | val testRun = MainScope().async { test() } 20 | while (testRun.isActive) { 21 | NSRunLoop.mainRunLoop.runMode( 22 | NSDefaultRunLoopMode, 23 | beforeDate = NSDate.create(timeInterval = 1.0, sinceDate = NSDate()), 24 | ) 25 | yield() 26 | } 27 | testRun.await() 28 | } 29 | actual fun runBlockingTest(action: suspend CoroutineScope.() -> Unit) = runBlocking(block = action) 30 | actual fun nativeMapOf(vararg pairs: Pair): Any = mapOf(*pairs) 31 | actual fun nativeListOf(vararg elements: Any?): Any = listOf(*elements) 32 | actual fun nativeAssertEquals(expected: Any?, actual: Any?) { 33 | kotlin.test.assertEquals(expected, actual) 34 | } 35 | -------------------------------------------------------------------------------- /test-utils/src/jsMain/kotlin/dev/gitlive/firebase/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | package dev.gitlive.firebase 6 | 7 | import kotlinx.coroutines.CoroutineScope 8 | import kotlin.js.json 9 | import kotlin.time.Duration.Companion.minutes 10 | 11 | actual fun runTest(test: suspend CoroutineScope.() -> Unit) = 12 | kotlinx.coroutines.test.runTest(timeout = 5.minutes) { test() } 13 | actual fun runBlockingTest(action: suspend CoroutineScope.() -> Unit) { 14 | kotlinx.coroutines.test.runTest { action() } 15 | } 16 | 17 | actual fun nativeMapOf(vararg pairs: Pair): Any = json(*pairs.map { (key, value) -> ((key as? String) ?: JSON.stringify(key)) to value }.toTypedArray()) 18 | actual fun nativeListOf(vararg elements: Any?): Any = elements 19 | actual fun nativeAssertEquals(expected: Any?, actual: Any?) { 20 | kotlin.test.assertEquals(JSON.stringify(expected), JSON.stringify(actual)) 21 | } 22 | -------------------------------------------------------------------------------- /test-utils/src/jvmMain/kotlin/dev/gitlive/firebase/TestUtils.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("TestUtilsJvm") 2 | /* 3 | * Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license. 4 | */ 5 | 6 | package dev.gitlive.firebase 7 | 8 | import android.app.Application 9 | import com.google.firebase.FirebasePlatform 10 | import kotlinx.coroutines.CoroutineScope 11 | import kotlinx.coroutines.runBlocking 12 | import kotlin.time.Duration.Companion.minutes 13 | 14 | val testContext = Application().apply { 15 | FirebasePlatform.initializeFirebasePlatform(object : FirebasePlatform() { 16 | val storage = mutableMapOf() 17 | override fun store(key: String, value: String) = storage.set(key, value) 18 | override fun retrieve(key: String) = storage[key] 19 | override fun clear(key: String) { 20 | storage.remove(key) 21 | } 22 | override fun log(msg: String) = println(msg) 23 | }) 24 | } 25 | 26 | actual fun runTest(test: suspend CoroutineScope.() -> Unit) = kotlinx.coroutines.test.runTest(timeout = 5.minutes) { test() } 27 | actual fun runBlockingTest(action: suspend CoroutineScope.() -> Unit) = runBlocking(block = action) 28 | 29 | actual fun nativeMapOf(vararg pairs: Pair): Any = mapOf(*pairs) 30 | actual fun nativeListOf(vararg elements: Any?): Any = listOf(*elements) 31 | actual fun nativeAssertEquals(expected: Any?, actual: Any?) { 32 | kotlin.test.assertEquals(expected, actual) 33 | } 34 | -------------------------------------------------------------------------------- /test/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "fir-kotlin-sdk" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/database.rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": true, 4 | ".write": true, 5 | "FirebaseRealtimeDatabaseTest": { 6 | "lastActivity": { 7 | ".validate": "!newData.exists() || newData.isNumber()" 8 | }, 9 | "nested": { 10 | "lastActivity": { 11 | ".validate": "!newData.exists() || newData.isNumber()" 12 | } 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /test/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "firestore": { 3 | "rules": "firestore.rules" 4 | }, 5 | "storage": { 6 | "rules": "storage.rules" 7 | }, 8 | "database": { 9 | "rules": "database.rules.json" 10 | }, 11 | "emulators": { 12 | "auth": { 13 | "port": 9099 14 | }, 15 | "firestore": { 16 | "port": 8080 17 | }, 18 | "database": { 19 | "port": 9000 20 | }, 21 | "storage": { 22 | "port": 9199 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/firestore.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service cloud.firestore { 3 | match /databases/{database}/documents { 4 | match /{document=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | --------------------------------------------------------------------------------