package com.example.firestoreapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ListenerRegistration
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FirestoreNotesScreen()
}
}
}
@Composable
fun FirestoreNotesScreen() {
val db = remember { FirebaseFirestore.getInstance() }
var noteText by remember { mutableStateOf("") }
var notes by remember { mutableStateOf(listOf<String>()) }
var listenerRegistration by remember { mutableStateOf<ListenerRegistration?>(null) }
DisposableEffect(Unit) {
listenerRegistration = db.collection("notes")
.addSnapshotListener { snapshot, error ->
if (error != null) {
// Handle error if needed
return@addSnapshotListener
}
if (snapshot != null) {
val noteList = snapshot.documents.mapNotNull { it.getString("text") }
notes = noteList
}
}
onDispose {
listenerRegistration?.remove()
}
}
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = noteText,
onValueChange = { noteText = it },
label = { Text("Enter note here...") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = {
if (noteText.isNotBlank()) {
val noteData = hashMapOf("text" to noteText.trim())
db.collection("notes").add(noteData)
noteText = ""
}
},
enabled = noteText.isNotBlank(),
modifier = Modifier.fillMaxWidth()
) {
Text("Add Note")
}
Spacer(modifier = Modifier.height(16.dp))
Text("Notes:", style = MaterialTheme.typography.titleMedium)
Spacer(modifier = Modifier.height(8.dp))
LazyColumn {
items(notes) { note ->
Text("- $note", style = MaterialTheme.typography.bodyLarge)
Spacer(modifier = Modifier.height(4.dp))
}
}
}
}This solution uses Jetpack Compose to build the UI and Firebase Firestore to store and retrieve notes.
We keep the note input text in a mutableStateOf variable to update the UI as the user types.
We listen to the Firestore 'notes' collection with addSnapshotListener to get real-time updates and update the notes list state.
The Add Note button is disabled when the input is empty to prevent empty notes.
When the button is clicked, the note is trimmed and added to Firestore, then the input is cleared.
The notes list is displayed below with a simple bullet style.