diff --git a/README.md b/README.md index fe4265a14..3d85498c1 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The following libraries are available for the various Firebase products. | Service or Product | Gradle Dependency | API Coverage | |---------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Analytics](https://firebase.google.com/docs/analytics) | [`dev.gitlive:firebase-analytics:1.12.0`](https://search.maven.org/artifact/dev.gitlive/firebase-analytics/1.12.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | | [Authentication](https://firebase.google.com/docs/auth) | [`dev.gitlive:firebase-auth:1.12.0`](https://search.maven.org/artifact/dev.gitlive/firebase-auth/1.12.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | | [Realtime Database](https://firebase.google.com/docs/database) | [`dev.gitlive:firebase-database:1.12.0`](https://search.maven.org/artifact/dev.gitlive/firebase-database/1.12.0/pom) | [![70%](https://img.shields.io/badge/-70%25-orange?style=flat-square)](/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt) | | [Cloud Firestore](https://firebase.google.com/docs/firestore) | [`dev.gitlive:firebase-firestore:1.12.0`](https://search.maven.org/artifact/dev.gitlive/firebase-firestore/1.12.0/pom) | [![60%](https://img.shields.io/badge/-60%25-orange?style=flat-square)](/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt) | diff --git a/firebase-messaging/src/androidMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt b/firebase-messaging/src/androidMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt index 17619585f..5fba05385 100644 --- a/firebase-messaging/src/androidMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt +++ b/firebase-messaging/src/androidMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt @@ -2,10 +2,19 @@ package dev.gitlive.firebase.messaging import dev.gitlive.firebase.Firebase +import kotlinx.coroutines.tasks.await actual val Firebase.messaging: FirebaseMessaging get() = FirebaseMessaging(com.google.firebase.messaging.FirebaseMessaging.getInstance()) actual class FirebaseMessaging(val android: com.google.firebase.messaging.FirebaseMessaging) { + actual fun subscribeToTopic(topic: String) { + android.subscribeToTopic(topic) + } + actual fun unsubscribeFromTopic(topic: String) { + android.unsubscribeFromTopic(topic) + } + + actual suspend fun getToken(): String = android.token.await() } \ No newline at end of file diff --git a/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt b/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt index ea8fa6e3d..3312bb795 100644 --- a/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt +++ b/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt @@ -6,4 +6,22 @@ import dev.gitlive.firebase.FirebaseApp /** Returns the [FirebaseMessaging] instance of the default [FirebaseApp]. */ expect val Firebase.messaging: FirebaseMessaging -expect class FirebaseMessaging +expect class FirebaseMessaging { + /** + * Subscribe to a topic. + * @param topic The topic to subscribe to. + */ + fun subscribeToTopic(topic: String) + + /** + * Unsubscribe from a topic. + * @param topic The topic to unsubscribe from. + */ + fun unsubscribeFromTopic(topic: String) + + /** + * Get FCM token for client + * @return [String] FCM token + */ + suspend fun getToken(): String +} \ No newline at end of file diff --git a/firebase-messaging/src/iosMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt b/firebase-messaging/src/iosMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt index 2f1897c52..b2511d86a 100644 --- a/firebase-messaging/src/iosMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt +++ b/firebase-messaging/src/iosMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt @@ -2,10 +2,44 @@ package dev.gitlive.firebase.messaging import cocoapods.FirebaseMessaging.FIRMessaging import dev.gitlive.firebase.Firebase +import kotlinx.coroutines.CompletableDeferred +import platform.Foundation.NSError actual val Firebase.messaging: FirebaseMessaging get() = FirebaseMessaging(FIRMessaging.messaging()) actual class FirebaseMessaging(val ios: FIRMessaging) { + actual fun subscribeToTopic(topic: String) { + ios.subscribeToTopic(topic) + } + actual fun unsubscribeFromTopic(topic: String) { + ios.unsubscribeFromTopic(topic) + } + + actual suspend fun getToken(): String = awaitResult { ios.tokenWithCompletion(it) } +} + +suspend inline fun T.await(function: T.(callback: (NSError?) -> Unit) -> Unit) { + val job = CompletableDeferred() + function { error -> + if(error == null) { + job.complete(Unit) + } else { + job.completeExceptionally(Exception(error.toString())) + } + } + job.await() +} + +suspend inline fun T.awaitResult(function: T.(callback: (R?, NSError?) -> Unit) -> Unit): R { + val job = CompletableDeferred() + function { result, error -> + if(error == null) { + job.complete(result) + } else { + job.completeExceptionally(Exception(error.toString())) + } + } + return job.await() as R } \ No newline at end of file diff --git a/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/externals/messaging.kt b/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/externals/messaging.kt index 506c8ef8f..5e6c48100 100644 --- a/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/externals/messaging.kt +++ b/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/externals/messaging.kt @@ -1,9 +1,12 @@ package dev.gitlive.firebase.messaging.externals import dev.gitlive.firebase.externals.FirebaseApp +import kotlin.js.Promise external fun getMessaging( app: FirebaseApp? = definedExternally, ): Messaging +external fun getToken(messaging: Messaging = definedExternally, options: dynamic = definedExternally): Promise + external interface Messaging \ No newline at end of file diff --git a/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt b/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt index dc809b68f..223a15338 100644 --- a/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt +++ b/firebase-messaging/src/jsMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt @@ -3,10 +3,24 @@ package dev.gitlive.firebase.messaging import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.messaging.externals.Messaging import dev.gitlive.firebase.messaging.externals.getMessaging +import kotlinx.coroutines.await + actual val Firebase.messaging: FirebaseMessaging get() = FirebaseMessaging(getMessaging()) actual class FirebaseMessaging(val js: Messaging) { + actual fun subscribeToTopic(topic: String) { + // This is not supported in the JS SDK + // https://firebase.google.com/docs/reference/js/messaging_.md#@firebase/messaging + throw NotImplementedError("Subscribing to topics is not supported in the JS SDK") + } + + actual fun unsubscribeFromTopic(topic: String) { + // This is not supported in the JS SDK + // https://firebase.google.com/docs/reference/js/messaging_.md#@firebase/messaging + throw NotImplementedError("Unsubscribing from topics is not supported in the JS SDK") + } + actual suspend fun getToken(): String = dev.gitlive.firebase.messaging.externals.getToken(js).await() } \ No newline at end of file diff --git a/firebase-messaging/src/jvmMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt b/firebase-messaging/src/jvmMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt index 6e13a52b2..6b8f3b82a 100644 --- a/firebase-messaging/src/jvmMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt +++ b/firebase-messaging/src/jvmMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt @@ -6,4 +6,16 @@ import dev.gitlive.firebase.Firebase actual val Firebase.messaging: FirebaseMessaging get() = TODO("Not yet implemented") -actual class FirebaseMessaging \ No newline at end of file +actual class FirebaseMessaging { + actual fun subscribeToTopic(topic: String) { + TODO("Not yet implemented") + } + + actual fun unsubscribeFromTopic(topic: String) { + TODO("Not yet implemented") + } + + actual suspend fun getToken(): String { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt index cf5fbc127..009c9027e 100644 --- a/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -64,14 +64,14 @@ class FirebaseStorageTest { @Test fun testUploadShouldNotCrash() = runBlockingTest { val data = createTestData() - val ref = storage.reference("test").child("testFile.txt") + val ref = storage.reference("test").child("testUploadShouldNotCrash.txt") ref.putData(data) } @Test fun testUploadMetadata() = runBlockingTest { val data = createTestData() - val ref = storage.reference("test").child("testFile.txt") + val ref = storage.reference("test").child("testUploadMetadata.txt") val metadata = storageMetadata { contentType = "text/plain" } @@ -87,7 +87,7 @@ class FirebaseStorageTest { @Test fun testUploadCustomMetadata() = runBlockingTest { val data = createTestData() - val ref = storage.reference("test").child("testFile.txt") + val ref = storage.reference("test").child("testUploadCustomMetadata.txt") val metadata = storageMetadata { contentType = "text/plain" setCustomMetadata("key", "value")