├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── drawable
│ │ │ │ ├── logo.png
│ │ │ │ ├── send.png
│ │ │ │ ├── edit_btn.xml
│ │ │ │ ├── sent_background.xml
│ │ │ │ ├── edit_background.xml
│ │ │ │ └── message_box_background.xml
│ │ │ ├── menu
│ │ │ │ └── menu.xml
│ │ │ ├── values
│ │ │ │ ├── ids.xml
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── themes.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── user_layout.xml
│ │ │ │ ├── receive.xml
│ │ │ │ ├── send.xml
│ │ │ │ ├── activity_chat.xml
│ │ │ │ ├── activity_login.xml
│ │ │ │ └── activity_sign_up.xml
│ │ │ └── values-night
│ │ │ │ └── themes.xml
│ │ ├── java
│ │ │ └── me
│ │ │ │ └── michigang1
│ │ │ │ └── michat
│ │ │ │ ├── User.kt
│ │ │ │ ├── Message.kt
│ │ │ │ ├── UserAdapter.kt
│ │ │ │ ├── MessageAdapter.kt
│ │ │ │ ├── Login.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── SignUp.kt
│ │ │ │ └── ChatActivity.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── me
│ │ │ └── michigang1
│ │ │ └── michat
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── me
│ │ └── michigang1
│ │ └── michat
│ │ └── ExampleInstrumentedTest.kt
├── google-services.json
└── build.gradle
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
├── gradle.properties
├── package.json
├── LICENSE
└── README.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michigang1/michat/HEAD/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michigang1/michat/HEAD/app/src/main/res/drawable/send.png
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/User.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | data class User(val name: String? = null, val email: String? = null, val uid: String? = null) {
4 |
5 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/edit_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/Message.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.text.Editable
4 |
5 | class Message(val message: String? = null, val senderID: String? = null) {
6 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sent_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/edit_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/message_box_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | android.useAndroidX=true
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | jcenter() // Warning: this repository is going to shut down soon
7 | }
8 | }
9 | rootProject.name = "michat"
10 | include ':app'
11 |
--------------------------------------------------------------------------------
/app/src/test/java/me/michigang1/michat/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | michat
3 | Name
4 | Email
5 | Password
6 | Sign Up
7 | Log In
8 | Log out
9 | Type a message
10 | send_message
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 | #FFAD33
11 | #FFC966
12 | #FFE4B3
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/michigang1/michat/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.michigang1.michat", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Tue Jun 07 16:19:14 CEST 2022
14 | android.useAndroidX=true
15 | android.enableJetifier=true
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/user_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
14 |
15 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "michat",
3 | "version": "1.0",
4 | "description": "The Kotlin Android application on Google Firebase",
5 | "keywords": [
6 | "kotlin",
7 | "android",
8 | "firebase",
9 | "google",
10 | "mobile",
11 | "java"
12 | ],
13 | "main": "src/main/java/me.michigang1.michat",
14 | "homepage": "https://michigang1.github.io/michat/",
15 | "bugs": {
16 | "url": "https://github.com/michigang1/michat/issues"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/michigang1/michat.git"
21 | },
22 | "license": "MIT",
23 | "author": {
24 | "name": "Michael Chirozidi",
25 | "email": "chirozidi.m@gmail.com",
26 | "url": "https://github.com/michigang1"
27 | },
28 | "dependencies": {
29 | "junit": "4.3.12",
30 | "firebase-bom": "30.1.0",
31 | "firebase-auth-ktx": "21.0.6",
32 | "firebase-database-ktx": "20.0.5",
33 | "gradle": "7.2.1",
34 | "google-services": "4.3.12"
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/receive.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/send.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Michael Chirozidi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "383987281399",
4 | "firebase_url": "https://michat-f4a07-default-rtdb.europe-west1.firebasedatabase.app",
5 | "project_id": "michat-f4a07",
6 | "storage_bucket": "michat-f4a07.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:383987281399:android:dd225b836ea52ae42092f2",
12 | "android_client_info": {
13 | "package_name": "me.michigang1.michat"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "383987281399-3h5ibv800rjutu0vane1e3mc7rlatuct.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyBwUAm8t17UPH97PPu-EiunVxBlc9YxVvo"
25 | }
26 | ],
27 | "services": {
28 | "appinvite_service": {
29 | "other_platform_oauth_client": [
30 | {
31 | "client_id": "383987281399-3h5ibv800rjutu0vane1e3mc7rlatuct.apps.googleusercontent.com",
32 | "client_type": 3
33 | }
34 | ]
35 | }
36 | }
37 | }
38 | ],
39 | "configuration_version": "1"
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/UserAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.TextView
9 | import androidx.recyclerview.widget.RecyclerView
10 |
11 | class UserAdapter(private val context: Context, private val userList: ArrayList):
12 | RecyclerView.Adapter() {
13 |
14 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
15 | val view: View = LayoutInflater.from(context).inflate(R.layout.user_layout, parent, false)
16 | return UserViewHolder(view)
17 |
18 | }
19 |
20 | override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
21 | val currentUser = userList[position]
22 | holder.textName.text = currentUser.name
23 | holder.itemView.setOnClickListener{
24 | val intent = Intent(context, ChatActivity::class.java)
25 | intent.putExtra("name", currentUser.name)
26 | intent.putExtra("uid", currentUser.uid)
27 | context.startActivity(intent)
28 | }
29 | }
30 |
31 | override fun getItemCount() = userList.size
32 |
33 | class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
34 | val textName: TextView = itemView.findViewById(R.id.txt_name)
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | id 'com.google.gms.google-services'
5 | }
6 |
7 | android {
8 | compileSdk 31
9 |
10 | defaultConfig {
11 | applicationId "me.michigang1.michat"
12 | minSdk 25
13 | targetSdk 31
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 | kotlinOptions {
31 | jvmTarget = '1.8'
32 | }
33 | }
34 |
35 | dependencies {
36 |
37 | implementation 'androidx.core:core-ktx:1.8.0'
38 | implementation 'androidx.appcompat:appcompat:1.4.2'
39 | implementation 'com.google.android.material:material:1.6.1'
40 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
41 | implementation 'com.google.firebase:firebase-auth:21.0.6'
42 | implementation 'com.google.firebase:firebase-database-ktx:20.0.5'
43 | implementation 'com.google.firebase:firebase-auth-ktx:21.0.6'
44 | testImplementation 'junit:junit:4.13.2'
45 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
46 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
47 | implementation platform('com.google.firebase:firebase-bom:30.1.0')
48 | implementation 'com.google.firebase:firebase-analytics-ktx'
49 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
23 |
24 |
37 |
38 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/MessageAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import com.google.firebase.auth.FirebaseAuth
10 |
11 | class MessageAdapter(private val context: Context, private val messageList: ArrayList):
12 | RecyclerView.Adapter() {
13 |
14 | private val itemReceive = 1
15 | private val itemSent = 2
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
18 | if (viewType == itemReceive) {
19 | val view: View = LayoutInflater.from(context).inflate(R.layout.receive, parent, false)
20 | return UserAdapter.UserViewHolder(view) }
21 | else {
22 | val view: View = LayoutInflater.from(context).inflate(R.layout.send, parent, false)
23 | return UserAdapter.UserViewHolder(view)
24 | }
25 |
26 | }
27 |
28 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
29 | val currentMessage = messageList[position]
30 | if (holder.javaClass == SentViewHolder::class.java) {
31 | val viewHolder = holder as SentViewHolder
32 | viewHolder.sentMessage.text = currentMessage.message.toString()
33 | }
34 | else {
35 | val viewHolder = holder as ReceiveViewHolder
36 | viewHolder.receiveMessage.text = currentMessage.message.toString()
37 | }
38 | }
39 |
40 | override fun getItemViewType(position: Int): Int {
41 | val currentMessage = messageList[position]
42 | val currentUser = FirebaseAuth.getInstance().currentUser?.uid
43 | return if (currentUser == currentMessage.senderID) itemSent
44 | else itemReceive
45 | }
46 |
47 | override fun getItemCount() = messageList.size
48 |
49 | class SentViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
50 | val sentMessage: TextView = itemView.findViewById(R.id.txt_sent_message)
51 |
52 | }
53 |
54 | class ReceiveViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
55 | val receiveMessage: TextView = itemView.findViewById(R.id.txt_receive_message)
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/Login.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 | import android.content.Intent
3 | import androidx.appcompat.app.AppCompatActivity
4 | import android.os.Bundle
5 | import android.widget.Button
6 | import android.widget.EditText
7 | import android.widget.Toast
8 | import com.google.firebase.auth.FirebaseAuth
9 | import com.google.firebase.auth.FirebaseUser
10 |
11 |
12 | class Login : AppCompatActivity() {
13 | private lateinit var editEmail: EditText
14 | private lateinit var editPassword: EditText
15 | private lateinit var btnLogin: Button
16 | private lateinit var btnSignUp: Button
17 |
18 | private lateinit var mAuth: FirebaseAuth
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | setContentView(R.layout.activity_login)
23 |
24 | supportActionBar?.hide()
25 |
26 | mAuth = FirebaseAuth.getInstance()
27 |
28 | editEmail = findViewById(R.id.edit_email)
29 | editPassword = findViewById(R.id.edit_password)
30 | btnLogin = findViewById(R.id.btnLogin)
31 | btnSignUp = findViewById(R.id.btnSignUp)
32 |
33 | btnSignUp.setOnClickListener{
34 | val intent = Intent(this, SignUp::class.java)
35 | startActivity(intent)
36 | }
37 |
38 | btnLogin.setOnClickListener {
39 | val email = editEmail.text.toString()
40 | val password = editPassword.text.toString()
41 |
42 | login(email, password)
43 | }
44 |
45 | }
46 |
47 | private fun login(email: String?, password: String?) {
48 | mAuth.signInWithEmailAndPassword(email!!, password!!)
49 | .addOnCompleteListener(this) { task ->
50 | if (task.isSuccessful) {
51 | val intent = Intent(this@Login, MainActivity::class.java)
52 | val currentUser = mAuth.currentUser
53 | updateUI(currentUser)
54 | finish()
55 | startActivity(intent)
56 | }
57 | else {
58 | Toast.makeText(this@Login, "User does not exist", Toast.LENGTH_SHORT).show()
59 | val currentUser = mAuth.currentUser
60 | updateUI(currentUser)
61 | }
62 | }
63 | }
64 |
65 | private fun updateUI(account: FirebaseUser?) {
66 | if (account != null) {
67 | Toast.makeText(this, "You logged-in in successfully", Toast.LENGTH_LONG).show()
68 | val intent = Intent(this, MainActivity::class.java)
69 | startActivity(intent)
70 | }
71 | else Toast.makeText(this, "Invalid password of email", Toast.LENGTH_LONG).show()
72 | }
73 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.os.Bundle
7 | import android.view.Menu
8 | import android.view.MenuItem
9 | import androidx.recyclerview.widget.LinearLayoutManager
10 | import androidx.recyclerview.widget.RecyclerView
11 | import com.google.firebase.auth.FirebaseAuth
12 | import com.google.firebase.database.*
13 |
14 | class MainActivity : AppCompatActivity() {
15 |
16 | private lateinit var userRecyclerView: RecyclerView
17 | private lateinit var userList: ArrayList
18 | private lateinit var userAdapter: UserAdapter
19 | private lateinit var mAuth: FirebaseAuth
20 | private lateinit var mDbRef: DatabaseReference
21 |
22 | override fun onCreate(savedInstanceState: Bundle?) {
23 | super.onCreate(savedInstanceState)
24 | setContentView(R.layout.activity_main)
25 |
26 | mAuth = FirebaseAuth.getInstance()
27 | mDbRef = FirebaseDatabase.getInstance().reference
28 |
29 | userList = ArrayList()
30 | userAdapter = UserAdapter(this@MainActivity, userList)
31 | userRecyclerView = findViewById(R.id.userRecyclerView)
32 | userRecyclerView.run {
33 | layoutManager = LinearLayoutManager(this@MainActivity)
34 | adapter = userAdapter
35 | }
36 |
37 | //logic for adding data to RecyclerView of users
38 | mDbRef.child("users").addValueEventListener(object: ValueEventListener{
39 | @SuppressLint("NotifyDataSetChanged")
40 | override fun onDataChange(snapshot: DataSnapshot) {
41 | userList.clear()
42 | for (postSnapshot in snapshot.children){
43 | val currentUser = snapshot.getValue(User::class.java)
44 | userList.add(currentUser!!)
45 | if(mAuth.currentUser?.uid != currentUser.uid){
46 | userList.add(currentUser)
47 | }
48 | }
49 | userAdapter.notifyDataSetChanged()
50 | }
51 |
52 | override fun onCancelled(error: DatabaseError) {
53 | TODO("Not yet implemented")
54 | }
55 |
56 | })
57 | }
58 |
59 | override fun onCreateOptionsMenu(menu: Menu?): Boolean {
60 | menuInflater.inflate(R.menu.menu, menu)
61 | return super.onCreateOptionsMenu(menu)
62 | }
63 |
64 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
65 | if(item.itemId == R.id.logOut){
66 | mAuth.signOut()
67 | val intent = Intent(this@MainActivity, Login::class.java)
68 | finish()
69 | startActivity(intent)
70 | return true
71 | }
72 | return true
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
33 |
34 |
48 |
49 |
60 |
61 |
72 |
73 |
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/SignUp.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.widget.Button
6 | import android.widget.EditText
7 | import android.widget.Toast
8 | import androidx.appcompat.app.AppCompatActivity
9 | import com.google.firebase.auth.FirebaseAuth
10 | import com.google.firebase.auth.FirebaseUser
11 | import com.google.firebase.database.DatabaseReference
12 | import com.google.firebase.database.FirebaseDatabase
13 |
14 |
15 | class SignUp : AppCompatActivity() {
16 | private lateinit var editName: EditText
17 | private lateinit var editEmail: EditText
18 | private lateinit var editPassword: EditText
19 | private lateinit var btnLogin: Button
20 | private lateinit var btnSignUp: Button
21 |
22 | private lateinit var mAuth: FirebaseAuth
23 | private lateinit var mDbRef: DatabaseReference
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 | setContentView(R.layout.activity_sign_up)
28 |
29 | supportActionBar?.hide()
30 |
31 | mAuth = FirebaseAuth.getInstance()
32 |
33 | editName = findViewById(R.id.edit_name)
34 | editEmail = findViewById(R.id.edit_email)
35 | editPassword = findViewById(R.id.edit_password)
36 | btnLogin = findViewById(R.id.btnLogin)
37 | btnSignUp = findViewById(R.id.btnSignUp)
38 |
39 | btnLogin.setOnClickListener{
40 | val intent = Intent(this, Login::class.java)
41 | startActivity(intent)
42 | }
43 |
44 | btnSignUp.setOnClickListener {
45 | val name = editName.text.toString()
46 | val email = editEmail.text.toString()
47 | val password = editPassword.text.toString()
48 |
49 | signUp(name, email, password)
50 | }
51 | }
52 |
53 | private fun signUp(name: String, email: String, password: String){
54 | mAuth.createUserWithEmailAndPassword(email, password)
55 | .addOnCompleteListener(this) { task ->
56 | if (task.isSuccessful) {
57 | addUserToDatabase(name,email,mAuth.currentUser?.uid!!)
58 | val intent = Intent(this@SignUp, MainActivity::class.java)
59 | val currentUser = mAuth.currentUser
60 | updateUI(currentUser)
61 | finish()
62 | startActivity(intent)
63 | }
64 | else{
65 | Toast.makeText(this@SignUp, "Authentication failed", Toast.LENGTH_SHORT).show()
66 | val currentUser = mAuth.currentUser
67 | updateUI(currentUser)
68 | }
69 |
70 | }
71 | }
72 |
73 | private fun addUserToDatabase(name: String, email: String, uid: String){
74 | mDbRef = FirebaseDatabase.getInstance().reference
75 | mDbRef.child("users").child("user: $uid").setValue(User(name, email, uid))
76 | }
77 |
78 | private fun updateUI(account: FirebaseUser?) {
79 | if (account != null) {
80 | Toast.makeText(this, "You signed in successfully", Toast.LENGTH_LONG).show()
81 | val intent = Intent(this, MainActivity::class.java)
82 | startActivity(intent)
83 | }
84 | else Toast.makeText(this, "You didn't signed in", Toast.LENGTH_LONG).show()
85 | }
86 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | >-----------------------------
3 | >
4 | >
5 | >
6 | >
7 | >
8 | >⠀⠀⠀⠀
9 | # michat
10 | > The Kotlin Android application using Google Firebase
11 | >
12 | > View [_here_](https://github.com/michigang1/michat/tree/main/app/src/main).
13 | -------------------------------
14 | ## Contents
15 | * [General Info](#general-information)
16 | * [Technologies Used](#technologies-used)
17 | * [Project Status](#project-status)
18 | * [Room for Improvement](#room-for-improvement)
19 | * [Acknowledgements](#acknowledgements)
20 | * [Contact](#contact)
21 |
22 |
23 |
24 | ## General Information
25 | - The application is a chat messenger.
26 | - The app uses registeration by password/emai.
27 | - My app allows people to communicate with each other without any restrictions (technical limitations do not count :) )
28 |
29 |
30 |
31 | ## Technologies Used
32 | - IDE: Android Studio
33 | - Language: Kotlin
34 | - Other instruments:
35 | - Google Firebase
36 | - XML
37 | - jUnit
38 | - MVP
39 |
40 |
41 |
42 | -->
45 |
46 |
47 |
51 |
52 |
53 |
54 | ## Project Status
55 | Project is: _in progress_
56 |
57 |
58 |
59 | ## Room for Improvement
60 |
61 | Room for improvement:
62 | - The chatting process needs improvement
63 | - The authentication process needs improvement
64 |
65 |
66 | To do:
67 | - other authentication options will be added (e.g., through a GitHub or Google account)
68 | - add the ability to send gifs/photos
69 | - voice recording
70 |
71 | Also offer your ideas in the https://github.com/michigang1/michat/discussions
72 |
73 |
74 |
75 | ## Acknowledgements
76 | - This project was inspired by my lecturer [Timur Shemsedinov](https://github.com/HowProgrammingWorks/Index/commits?author=tshemsedinov)
77 |
78 |
79 |
80 |
81 |
82 | ## Contact
83 | Created by Michael Chirozidi - [my telegram](https://telegram.me/poor_boy) - feel free to contact me!
84 |
85 |
86 |
87 | ## License
88 | [MIT](LICENSE.md)
89 |
--------------------------------------------------------------------------------
/app/src/main/java/me/michigang1/michat/ChatActivity.kt:
--------------------------------------------------------------------------------
1 | package me.michigang1.michat
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.os.Bundle
7 | import android.widget.EditText
8 | import android.widget.ImageView
9 | import androidx.recyclerview.widget.LinearLayoutManager
10 | import androidx.recyclerview.widget.RecyclerView
11 | import com.google.firebase.auth.FirebaseAuth
12 | import com.google.firebase.database.*
13 |
14 | class ChatActivity : AppCompatActivity() {
15 |
16 | private lateinit var messageRecyclerView: RecyclerView
17 | private lateinit var messageBox: EditText
18 | private lateinit var messageAdapter: MessageAdapter
19 | private lateinit var messageList: ArrayList
20 | private lateinit var btnSend: ImageView
21 | private lateinit var mAuth: FirebaseAuth
22 | private lateinit var mDbRef: DatabaseReference
23 |
24 | var senderRoom: String? = null
25 | var receiverRoom: String? = null
26 |
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | super.onCreate(savedInstanceState)
29 | setContentView(R.layout.activity_chat)
30 |
31 | mAuth = FirebaseAuth.getInstance()
32 | mDbRef = FirebaseDatabase.getInstance().reference
33 |
34 | val intent = Intent()
35 | val name = intent.getStringExtra("name")
36 |
37 | supportActionBar?.title = name
38 |
39 | val receiverUid = intent.getStringExtra("uid")
40 | val senderUid = mAuth.currentUser?.uid
41 |
42 | senderRoom = senderUid + receiverUid
43 | receiverRoom = receiverUid + senderUid
44 |
45 |
46 | messageBox = findViewById(R.id.messageBox)
47 | btnSend = findViewById(R.id.btnSend)
48 | messageRecyclerView = findViewById(R.id.messageRecyclerView)
49 |
50 | messageList = ArrayList()
51 | messageAdapter = MessageAdapter(this, messageList)
52 | messageRecyclerView.run {
53 | layoutManager = LinearLayoutManager(this@ChatActivity)
54 | adapter = messageAdapter
55 | }
56 |
57 | //logic for adding to RecyclerView of messages
58 | mDbRef.child("chats").child(senderRoom!!).child("messages")
59 | .addValueEventListener(object: ValueEventListener{
60 | @SuppressLint("NotifyDataSetChanged")
61 | override fun onDataChange(snapshot: DataSnapshot) {
62 | for (postSnapshot in snapshot.children){
63 | val message = postSnapshot.getValue(Message::class.java)
64 | messageList.add(message!!)
65 | }
66 | messageAdapter.notifyDataSetChanged()
67 | }
68 |
69 | override fun onCancelled(error: DatabaseError) {
70 | TODO("Not yet implemented")
71 | }
72 | })
73 |
74 | // adding to database
75 | btnSend.setOnClickListener {
76 | val message = messageBox.text.toString()
77 | val messageObject = Message(message, senderUid)
78 |
79 | mDbRef.child("chats").child(senderRoom!!).child("messages").push()
80 | .setValue(messageObject).addOnSuccessListener {
81 | mDbRef.child("chats").child(receiverRoom!!).child("messages").push()
82 | .setValue(messageObject)
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_sign_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
32 |
33 |
47 |
48 |
62 |
63 |
74 |
75 |
86 |
87 |
--------------------------------------------------------------------------------