0% found this document useful (0 votes)
12 views10 pages

Android Notes App with Firebase Integration

The document outlines the structure and implementation of an Android project using Kotlin, including Gradle configuration, main activity, login and registration activities, and a RecyclerView for displaying notes. It utilizes Firebase for authentication and Firestore for data storage, with asynchronous operations handled by Kotlin Coroutines. The UI is defined using XML layouts for each activity, facilitating user interaction for note management.

Uploaded by

mudianto7717
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views10 pages

Android Notes App with Firebase Integration

The document outlines the structure and implementation of an Android project using Kotlin, including Gradle configuration, main activity, login and registration activities, and a RecyclerView for displaying notes. It utilizes Firebase for authentication and Firestore for data storage, with asynchronous operations handled by Kotlin Coroutines. The UI is defined using XML layouts for each activity, facilitating user interaction for note management.

Uploaded by

mudianto7717
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Project structure:

[Link] (project)
// Top-level build file where you can add configuration options common to
all sub-projects/modules.
plugins {
alias([Link]) apply false
alias([Link]) apply false
}

[Link] (App)
plugins {
alias([Link])
alias([Link])
}

android {
namespace = "[Link]"
compileSdk = 34

defaultConfig {
applicationId = "[Link]"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner =
"[Link]"
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("[Link]"),
"[Link]"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
}

dependencies {

// Firebase BoM (manage versions automatically)


implementation(platform("[Link]:firebase-bom:34.4.0"))

// Firebase Authentication
implementation("[Link]:firebase-auth-ktx")

// Firebase Firestore
implementation("[Link]:firebase-firestore-ktx")

// Kotlin Coroutines (for async operations)


implementation("[Link]:kotlinx-coroutines-
android:1.7.3")

implementation([Link])
implementation([Link])
implementation([Link])
implementation([Link])
implementation([Link])
implementation([Link])
implementation([Link])
testImplementation([Link])
androidTestImplementation([Link])
androidTestImplementation([Link])
}

Main Activity
package [Link]

import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]

class MainActivity : AppCompatActivity() {


private val repo = FirebaseRepository()
private val adapter = NotesAdapter(mutableListOf())

@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
[Link](savedInstanceState)
setContentView([Link].activity_main)

val btnSignOut = findViewById<Button>([Link])


val btnAdd = findViewById<Button>([Link])
val etNote = findViewById<EditText>([Link])
val rvNotes = findViewById<RecyclerView>([Link])

[Link] = LinearLayoutManager(this)
[Link] = adapter

[Link] {
[Link]()
startActivity(Intent(this, LoginActivity::[Link]))
finish()
}

[Link] {
val text = [Link]().trim()
if ([Link]()) return@setOnClickListener

CoroutineScope([Link]).launch {
val res = [Link](text)
withContext([Link]) {
if ([Link]) {
[Link]()
loadNotes()
} else {
[Link](
this@MainActivity,
[Link]()?.localizedMessage ?: "Add
failed",
Toast.LENGTH_LONG
).show()
}
}
}
}

loadNotes()
}

private fun loadNotes() {


CoroutineScope([Link]).launch {
val res = [Link]()
withContext([Link]) {
if ([Link]) {
[Link]([Link](emptyList()))
} else {
[Link](
this@MainActivity,
[Link]()?.localizedMessage ?: "Load
failed",
Toast.LENGTH_LONG
).show()
}
}
}
}
}

/* Minimal RecyclerView Adapter kept in same file for simplicity.


Move to its own file if you prefer cleaner structure. */
class NotesAdapter(private val items: MutableList<Note>) :
[Link]<[Link]>() {

inner class VH(val v: [Link]) : [Link](v)

override fun onCreateViewHolder(parent: [Link],


viewType: Int): VH {
val v = [Link]([Link])
.inflate([Link].item_note, parent, false)
return VH(v)
}

override fun onBindViewHolder(holder: VH, position: Int) {


val note = items[position]
val tv =
[Link]<[Link]>([Link])
[Link] = [Link]

[Link] {
// optional: delete note on long press
val id = [Link]
if ([Link]()) {
CoroutineScope([Link]).launch {
val repo = FirebaseRepository()
val res = [Link](id)
withContext([Link]) {
if ([Link]) {
[Link](position)
notifyItemRemoved(position)
} else {
[Link](
[Link],
[Link]()?.localizedMessage ?:
"Delete failed",
Toast.LENGTH_LONG
).show()
}
}
}
}
true
}
}

override fun getItemCount(): Int = [Link]

fun setItems(newItems: List<Note>) {


[Link]()
[Link](newItems)
notifyDataSetChanged()
}
}

xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">

<Button
android:id="@+id/btnSignOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign Out" />

<EditText
android:id="@+id/etNote"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter note"
android:layout_marginTop="12dp"
android:inputType="text" />

<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Note"
android:layout_marginTop="8dp" />
<[Link]
android:id="@+id/rvNotes"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="12dp"
android:layout_weight="1"
android:scrollbars="vertical" />
</LinearLayout>

login activity
package [Link]

import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]

class LoginActivity : AppCompatActivity() {

private val repo = FirebaseRepository()

override fun onCreate(savedInstanceState: Bundle?) {


[Link](savedInstanceState)
setContentView([Link].activity_login)

val etEmail = findViewById<EditText>([Link])


val etPassword = findViewById<EditText>([Link])
val btnLogin = findViewById<Button>([Link])
val tvRegister = findViewById<TextView>([Link])

[Link] {
val email = [Link]().trim()
val pass = [Link]().trim()

if ([Link]() || [Link]()) {
[Link](this, "Enter email and password",
Toast.LENGTH_SHORT).show()
return@setOnClickListener
}

CoroutineScope([Link]).launch {
val res = [Link](email, pass)
withContext([Link]) {
if ([Link]) {
startActivity(Intent(this@LoginActivity,
MainActivity::[Link]))
finish()
} else {
[Link](
this@LoginActivity,
[Link]()?.localizedMessage ?:
"Login failed",
Toast.LENGTH_LONG
).show()
}
}
}
}

[Link] {
startActivity(Intent(this, RegisterActivity::[Link]))
}
}
}

xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center_horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login"
android:textSize="24sp"
android:textStyle="bold"
android:layout_marginBottom="24dp" />

<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress"
android:layout_marginBottom="12dp" />

<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword"
android:layout_marginBottom="16dp" />

<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login" />

<TextView
android:id="@+id/tvRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Don't have an account? Register"
android:textColor="@android:color/holo_blue_dark"
android:layout_marginTop="20dp" />
</LinearLayout>

register activity
package [Link]

import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]

class RegisterActivity : AppCompatActivity() {

private val repo = FirebaseRepository()

override fun onCreate(savedInstanceState: Bundle?) {


[Link](savedInstanceState)
setContentView([Link].activity_register)

val etEmail = findViewById<EditText>([Link])


val etPassword = findViewById<EditText>([Link])
val etConfirmPassword =
findViewById<EditText>([Link])
val btnRegister = findViewById<Button>([Link])
val tvLogin = findViewById<TextView>([Link])

[Link] {
val email = [Link]().trim()
val password = [Link]().trim()
val confirmPassword = [Link]().trim()

if ([Link]() || [Link]() ||
[Link]()) {
[Link](this, "All fields are required",
Toast.LENGTH_SHORT).show()
return@setOnClickListener
}

if (password != confirmPassword) {
[Link](this, "Passwords do not match",
Toast.LENGTH_SHORT).show()
return@setOnClickListener
}

CoroutineScope([Link]).launch {
val result = [Link](email, password)
withContext([Link]) {
if ([Link]) {
[Link](this@RegisterActivity, "Registration
successful", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@RegisterActivity,
LoginActivity::[Link]))
finish()
} else {
[Link](
this@RegisterActivity,
[Link]()?.localizedMessage ?:
"Registration failed",
Toast.LENGTH_LONG
).show()
}
}
}
}

[Link] {
startActivity(Intent(this, LoginActivity::[Link]))
finish()
}
}
}

xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center_horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Register"
android:textSize="24sp"
android:textStyle="bold"
android:layout_marginBottom="24dp" />

<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress"
android:layout_marginBottom="12dp" />

<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword"
android:layout_marginBottom="12dp" />

<EditText
android:id="@+id/etConfirmPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Confirm Password"
android:inputType="textPassword"
android:layout_marginBottom="16dp" />
<Button
android:id="@+id/btnRegister"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register" />

<TextView
android:id="@+id/tvLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Already have an account? Login"
android:textColor="@android:color/holo_blue_dark"
android:layout_marginTop="20dp" />
</LinearLayout>

[Link]:

package [Link]

data class Note(


var id: String = "",
var text: String = ""
)

You might also like