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

Compose Firebase InAppMessaging #1498

Open
wants to merge 1 commit into
base: compose
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions inappmessaging/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
13 changes: 4 additions & 9 deletions inappmessaging/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,11 @@
android:theme="@style/AppTheme">

<activity
android:name="com.google.firebase.fiamquickstart.java.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</activity>

android:name="com.google.firebase.fiamquickstart.java.MainActivity"/>
<activity
android:name="com.google.firebase.fiamquickstart.kotlin.KotlinMainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</activity>
android:name="com.google.firebase.fiamquickstart.kotlin.KotlinMainActivity"/>
<activity
android:name="com.google.firebase.fiamquickstart.kotlin.ComposeMainActivity"/>

<activity android:name="com.google.firebase.fiamquickstart.EntryChoiceActivity"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Choice> {
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))
)
}
}
Original file line number Diff line number Diff line change
@@ -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<String> = 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()
}
}
Original file line number Diff line number Diff line change
@@ -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<String> = _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 <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val firebaseAnalytics = Firebase.analytics
val firebaseIam = Firebase.inAppMessaging
val firebaseInstallations = Firebase.installations
return InAppMessagingViewModel(firebaseAnalytics, firebaseIam, firebaseInstallations) as T
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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)
)
Loading