Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messaging improvements #536

Merged
merged 10 commits into from
Jun 20, 2024
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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> T.await(function: T.(callback: (NSError?) -> Unit) -> Unit) {
val job = CompletableDeferred<Unit>()
function { error ->
if(error == null) {
job.complete(Unit)
} else {
job.completeExceptionally(Exception(error.toString()))
}
}
job.await()
}

suspend inline fun <T, reified R> T.awaitResult(function: T.(callback: (R?, NSError?) -> Unit) -> Unit): R {
val job = CompletableDeferred<R?>()
function { result, error ->
if(error == null) {
job.complete(result)
} else {
job.completeExceptionally(Exception(error.toString()))
}
}
return job.await() as R
}
Original file line number Diff line number Diff line change
@@ -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<String>

external interface Messaging
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,16 @@ import dev.gitlive.firebase.Firebase
actual val Firebase.messaging: FirebaseMessaging
get() = TODO("Not yet implemented")

actual class FirebaseMessaging
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")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand All @@ -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")
Expand Down
Loading