diff --git a/inappmessaging/app/build.gradle b/inappmessaging/app/build.gradle
index 00b6c2746..fa35f09ec 100644
--- a/inappmessaging/app/build.gradle
+++ b/inappmessaging/app/build.gradle
@@ -85,6 +85,7 @@ dependencies {
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.activity:activity-compose:1.5.1'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/inappmessaging/app/src/main/AndroidManifest.xml b/inappmessaging/app/src/main/AndroidManifest.xml
index f9816bcd6..e8fd0ab3e 100644
--- a/inappmessaging/app/src/main/AndroidManifest.xml
+++ b/inappmessaging/app/src/main/AndroidManifest.xml
@@ -10,16 +10,11 @@
android:theme="@style/AppTheme">
-
-
+ android:name="com.google.firebase.fiamquickstart.java.MainActivity"/>
-
+ android:name="com.google.firebase.fiamquickstart.kotlin.KotlinMainActivity"/>
+
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/EntryChoiceActivity.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/EntryChoiceActivity.kt
index efe54c42c..d29b9fa50 100644
--- a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/EntryChoiceActivity.kt
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/EntryChoiceActivity.kt
@@ -4,20 +4,25 @@ import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
import com.google.firebase.fiamquickstart.java.MainActivity
+import com.google.firebase.fiamquickstart.kotlin.ComposeMainActivity
import com.google.firebase.fiamquickstart.kotlin.KotlinMainActivity
class EntryChoiceActivity : BaseEntryChoiceActivity() {
override fun getChoices(): List {
return listOf(
- Choice(
- "Java",
- "Run the Firebase In App Messaging quickstart written in Java.",
- Intent(this, MainActivity::class.java)),
- Choice(
- "Kotlin",
- "Run the Firebase In App Messaging quickstart written in Kotlin.",
- Intent(this, KotlinMainActivity::class.java))
+ Choice(
+ "Java",
+ "Run the Firebase In App Messaging quickstart written in Java.",
+ Intent(this, MainActivity::class.java)),
+ Choice(
+ "Kotlin",
+ "Run the Firebase In App Messaging quickstart written in Kotlin.",
+ Intent(this, KotlinMainActivity::class.java)),
+ Choice(
+ "Compose",
+ "Run the Firebase In App Messaging quickstart written in Compose.",
+ Intent(this, ComposeMainActivity::class.java))
)
}
}
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/ComposeMainActivity.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/ComposeMainActivity.kt
new file mode 100644
index 000000000..75168ed5e
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/ComposeMainActivity.kt
@@ -0,0 +1,162 @@
+package com.google.firebase.fiamquickstart.kotlin
+
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Scaffold
+import androidx.compose.material.SnackbarHostState
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.rememberScaffoldState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.google.firebase.fiamquickstart.R
+import com.google.firebase.fiamquickstart.kotlin.ui.theme.InAppMessagingTheme
+import kotlinx.coroutines.launch
+
+class ComposeMainActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ InAppMessagingTheme {
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colors.background
+ ) {
+ MainAppView()
+ }
+ }
+ }
+ }
+
+ companion object {
+ private const val TAG = "Compose-FIAM-Quickstart"
+ }
+}
+
+@Composable
+fun MainAppView(
+ inAppMessagingViewModel: InAppMessagingViewModel = viewModel(factory = InAppMessagingViewModel.Factory)
+) {
+ val snackbarHostState = remember { SnackbarHostState() }
+ val scope = rememberCoroutineScope()
+ val scaffoldState = rememberScaffoldState(snackbarHostState = snackbarHostState)
+
+ Scaffold(
+ scaffoldState = scaffoldState,
+ content = {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(it)
+ ) {
+ MainContent(
+ _installationsId = inAppMessagingViewModel.installationsId.collectAsState(""),
+ triggerEvent = {
+ inAppMessagingViewModel.triggerEvent()
+ scope.launch {
+ snackbarHostState.showSnackbar("engagement_party' event triggered!")
+ }
+ }
+ )
+ }
+ }
+ )
+}
+
+@Composable
+fun MainContent(
+ _installationsId: State = mutableStateOf(""),
+ triggerEvent: ()-> Unit = {}
+) {
+ val installationsId by remember { _installationsId }
+
+ Column(
+ modifier = Modifier
+ .padding(16.dp)
+ .fillMaxWidth(),
+ ) {
+ Image(
+ painter = painterResource(R.drawable.firebase_lockup_400),
+ contentDescription = "",
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(8.dp),
+ alignment = Alignment.Center
+ )
+
+ Text(
+ text = stringResource(R.string.textview_text),
+ fontSize = 18.sp,
+ style = MaterialTheme.typography.h6,
+ modifier = Modifier.padding(top = 8.dp, start = 8.dp, end = 8.dp)
+ )
+
+ Text(
+ text = stringResource(R.string.warning_fresh_install),
+ fontSize = 18.sp,
+ style = MaterialTheme.typography.h6,
+ modifier = Modifier.padding(top = 16.dp, start = 8.dp, end = 8.dp, bottom = 8.dp)
+ )
+
+ Text(
+ text = if(installationsId.isEmpty()){
+ "Device Instance ID: 1234"
+ } else {
+ stringResource(R.string.installation_id_fmt, installationsId)
+ },
+ fontSize = 18.sp,
+ style = MaterialTheme.typography.h6,
+ modifier = Modifier.padding(top = 16.dp, start = 8.dp, end = 8.dp, bottom = 8.dp)
+ )
+
+ Button(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(8.dp),
+ colors = ButtonDefaults.buttonColors(backgroundColor = colorResource(R.color.colorPrimary)),
+ onClick = {
+ triggerEvent()
+ }
+ ) {
+ Text(
+ text = stringResource(R.string.button_text).uppercase(),
+ color = Color.White
+ )
+ }
+ }
+}
+
+
+@Composable
+@Preview(showBackground = true)
+fun MainContentPreview(){
+ InAppMessagingTheme {
+ MainContent()
+ }
+}
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/InAppMessagingViewModel.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/InAppMessagingViewModel.kt
new file mode 100644
index 000000000..024cd06b8
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/InAppMessagingViewModel.kt
@@ -0,0 +1,66 @@
+package com.google.firebase.fiamquickstart.kotlin
+
+import android.os.Bundle
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.CreationExtras
+import com.google.firebase.analytics.FirebaseAnalytics
+import com.google.firebase.analytics.ktx.analytics
+import com.google.firebase.inappmessaging.FirebaseInAppMessaging
+import com.google.firebase.inappmessaging.ktx.inAppMessaging
+import com.google.firebase.installations.FirebaseInstallations
+import com.google.firebase.installations.ktx.installations
+import com.google.firebase.ktx.Firebase
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.tasks.await
+
+class InAppMessagingViewModel(
+ private val firebaseAnalytics: FirebaseAnalytics,
+ firebaseIam: FirebaseInAppMessaging,
+ private val firebaseInstallations: FirebaseInstallations,
+): ViewModel() {
+
+ private val _installationsId = MutableStateFlow("")
+ val installationsId: StateFlow = _installationsId
+
+ init {
+ firebaseIam.isAutomaticDataCollectionEnabled = true
+ firebaseIam.setMessagesSuppressed(false)
+
+ viewModelScope.launch {
+ try {
+ val id = firebaseInstallations.id.await()
+ _installationsId.value = id
+ } catch (e: Exception) {
+ Log.e(TAG, e.toString())
+ }
+ }
+ }
+
+ fun triggerEvent(){
+ firebaseAnalytics.logEvent("engagement_party", Bundle())
+ }
+
+ companion object {
+ const val TAG = "InAppMessagingViewModel"
+
+ // Used to inject this ViewModel's dependencies
+ // See also: https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-factories
+ val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
+ @Suppress("UNCHECKED_CAST")
+ override fun create(
+ modelClass: Class,
+ extras: CreationExtras
+ ): T {
+ val firebaseAnalytics = Firebase.analytics
+ val firebaseIam = Firebase.inAppMessaging
+ val firebaseInstallations = Firebase.installations
+ return InAppMessagingViewModel(firebaseAnalytics, firebaseIam, firebaseInstallations) as T
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/KotlinMainActivity.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/KotlinMainActivity.kt
index 807a55ed8..c2c459800 100644
--- a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/KotlinMainActivity.kt
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/KotlinMainActivity.kt
@@ -1,51 +1,41 @@
package com.google.firebase.fiamquickstart.kotlin
import android.os.Bundle
-import android.util.Log
+import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
import com.google.android.material.snackbar.Snackbar
-import com.google.firebase.analytics.FirebaseAnalytics
-import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.fiamquickstart.R
import com.google.firebase.fiamquickstart.databinding.ActivityMainBinding
-import com.google.firebase.inappmessaging.FirebaseInAppMessaging
-import com.google.firebase.inappmessaging.ktx.inAppMessaging
-import com.google.firebase.installations.ktx.installations
-import com.google.firebase.ktx.Firebase
+import kotlinx.coroutines.launch
class KotlinMainActivity : AppCompatActivity() {
- private lateinit var firebaseAnalytics: FirebaseAnalytics
- private lateinit var firebaseIam: FirebaseInAppMessaging
+ private val viewModel: InAppMessagingViewModel by viewModels { InAppMessagingViewModel.Factory }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
- firebaseAnalytics = Firebase.analytics
- firebaseIam = Firebase.inAppMessaging
-
- firebaseIam.isAutomaticDataCollectionEnabled = true
- firebaseIam.setMessagesSuppressed(false)
-
binding.eventTriggerButton.setOnClickListener { view ->
- firebaseAnalytics.logEvent("engagement_party", Bundle())
+ viewModel.triggerEvent()
Snackbar.make(view, "'engagement_party' event triggered!", Snackbar.LENGTH_LONG)
- .setAction("Action", null)
- .show()
+ .setAction("Action", null)
+ .show()
}
// Get and display/log the installation id
- Firebase.installations.getId()
- .addOnSuccessListener { id ->
- binding.installationIdText.text = getString(R.string.installation_id_fmt, id)
- Log.d(TAG, "Installation ID: $id")
+ lifecycleScope.launch {
+ viewModel.installationsId.collect {
+ if (it.isNotEmpty()) {
+ binding.installationIdText.text = getString(R.string.installation_id_fmt, it)
}
+ }
+ }
}
companion object {
-
private const val TAG = "FIAM-Quickstart"
}
}
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Color.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Color.kt
new file mode 100644
index 000000000..b27e6b03c
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Color.kt
@@ -0,0 +1,11 @@
+package com.google.firebase.fiamquickstart.kotlin.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val FirebaseBlue = Color(0xFF0288D1) // copied from colors.xml
+val FirebaseBannerBlue = Color(0xFF039BE5) // copied from colors.xml
+val FirebaseOrange = Color(0xFFFFA000) // copied from colors.xml
\ No newline at end of file
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Shape.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Shape.kt
new file mode 100644
index 000000000..bbbc4c465
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.google.firebase.fiamquickstart.kotlin.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(16.dp),
+ medium = RoundedCornerShape(2.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Theme.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Theme.kt
new file mode 100644
index 000000000..d60199da8
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Theme.kt
@@ -0,0 +1,48 @@
+package com.google.firebase.fiamquickstart.kotlin.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple80,
+ primaryVariant = PurpleGrey80,
+ secondary = Pink80
+)
+
+private val LightColorPalette = lightColors(
+ primary = FirebaseBlue,
+ primaryVariant = FirebaseBannerBlue,
+ secondary = FirebaseOrange
+
+ /* Other default colors to override
+ background = Color(0xFFFFFBFE),
+ surface = Color(0xFFFFFBFE),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ onTertiary = Color.White,
+ onBackground = Color(0xFF1C1B1F),
+ onSurface = Color(0xFF1C1B1F),
+ */
+)
+
+@Composable
+fun InAppMessagingTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ content: @Composable () -> Unit
+) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Type.kt b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Type.kt
new file mode 100644
index 000000000..0f280144f
--- /dev/null
+++ b/inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/kotlin/theme/Type.kt
@@ -0,0 +1,34 @@
+package com.google.firebase.fiamquickstart.kotlin.ui.theme
+
+import androidx.compose.material.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.5.sp
+ )
+ /* Other default text styles to override
+ titleLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.sp
+ ),
+ labelSmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Medium,
+ fontSize = 11.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.5.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/inappmessaging/gradle.properties b/inappmessaging/gradle.properties
index aac7c9b46..29b531a1d 100644
--- a/inappmessaging/gradle.properties
+++ b/inappmessaging/gradle.properties
@@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
-
+android.useAndroidX=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects