I´m new in this thing, I have used a tutorial as guide, I copy everything correct from the tutorial, but when I want to run the app I can´t because the following warnings appear:
Unresolved reference: isSuccesful
Unresolved reference: result
Unresolved reference: isSuccesful
Unresolved reference: result
Unresolved reference: FirebaseAuth
Here´s my code:
package com.mpdw55.medic_app
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlinx.android.synthetic.main.activity_auth.*
class AuthActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_auth)
// Analytics Event
val analytics:FirebaseAnalytics = FirebaseAnalytics.getInstance(this)
val bundle = Bundle()
bundle.putString("message", "Integracón de Firebase completa")
analytics.logEvent("Initscreen", bundle)
//setup
setup()
}
private fun setup(){
title = "Autenticación"
signUpButton.setOnClickListener {
if (emailEditTest.text.isNotEmpty() && passwordEditText.text.isNotEmpty()) {
FirebaseAuth.getInstance()
.createUserWithEmailAndPassword(emailEditTest.text.toString(),
passwordEditText.text.toString()).addOnCompleteListener {}
if (it.isSuccesful) {
showHome(it.result?.user?.email?:"", ProviderType.BASIC)
} else {
showAlert()
}
}
}
logInButton.setOnClickListener {
if (emailEditTest.text.isNotEmpty() && passwordEditText.text.isNotEmpty()) {
FirebaseAuth.getInstance()
.signInWithEmailAndPassword(emailEditTest.text.toString(),
passwordEditText.text.toString()).addOnCompleteListener {}
if (it.isSuccesful) {
showHome(it.result?.user?.email?:"", ProviderType.BASIC)
} else {
showAlert()
}
}
}
}
private fun showAlert() {
val builder = AlertDialog.Builder(this)
builder.setTitle("Error")
builder.setMessage("Se ha producido un error autenticando al ususario")
builder.setPositiveButton("Aceptar", null)
val dialog: AlertDialog = builder.create()
dialog.show()
}
private fun showHome(email: String, provider: ProviderType){
val homeIntent = Intent(this, HomeActivity::class.java).apply {
putExtra("email", email)
putExtra("provider", provider.name)
}
startActivity(homeIntent)
}
My build.gradle(:app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.1"
defaultConfig {
applicationId "com.mpdw55.medic_app"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.firebase:firebase-core:17.4.4'
implementation 'com.google.firebase:firebase-analytics:17.4.4'
implementation 'com.google.firebase:firebase-auth:19.3.2'
implementation 'com.google.android.gms:play-services-auth:18.1.0'
implementation 'com.firebaseui:firebase-ui-auth:6.3.0'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
apply plugin: 'com.google.gms.google-services'
Can someone help me ??
you should try to put the if(it.isSuccesfull){}else{} in between the brackets for the .addOnCompleteListener the result should be something
FirebaseAuth.getInstance()
.createUserWithEmailAndPassword(emailEditTest.text.toString(),
passwordEditText.text.toString()).addOnCompleteListener {
if (it.isSuccesful) {
showHome(it.result?.user?.email?:"", ProviderType.BASIC)
} else {
showAlert()
} }
And the error should be solved. You should also do the same for the sing in.
logInButton.setOnClickListener {
if (emailEditTest.text.isNotEmpty() && passwordEditText.text.isNotEmpty()) {
FirebaseAuth.getInstance()
.signInWithEmailAndPassword(emailEditTest.text.toString(),
passwordEditText.text.toString()).addOnCompleteListener {
if (it.isSuccesful) {
showHome(it.result?.user?.email?:"", ProviderType.BASIC)
} else {
showAlert()
}}
Related
I have been following a tutorial from Geeks for Geeks on how to make a simple note app for Android. I've practically copied to code word-by-word (except for a minor fix in the gradle file as advised from a Stack Overflow post and a comment in the YouTube comment section), yet the app crashes every time I open it even after clearing all the caches and rebuilding the project.
Links:
https://www.geeksforgeeks.org/how-to-build-a-simple-note-android-app-using-mvvm-and-room-database/
https://www.youtube.com/watch?v=D2F5t-phP04
Now, I know the problem with the code stems from the below command line.
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(NoteViewModel::class.java)
Every time I include the above line and launch the app, the app crashes, and my phone cannot open it. Commenting out the above line and the code below it allows the app to be opened without an issue.
(App gradle)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.notepractice"
minSdk 26
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)
implementation 'androidx.fragment:fragment-ktx:1.1.0'
// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
annotationProcessor "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}
(Project gradle)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.31"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle-api:7.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'com.android.application' version '7.2.0' apply false
id 'com.android.library' version '7.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
allprojects {
repositories {
google()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
/*
ext {
activityVersion = '1.4.0'
appCompatVersion = '1.4.0'
constraintLayoutVersion = '2.1.2'
coreTestingVersion = '2.1.0'
coroutines = '1.5.2'
lifecycleVersion = '2.4.0'
materialVersion = '1.4.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.4.0'
androidxJunitVersion = '1.1.3'
}
*/
ext {
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.5.0'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
(Main Activity)
package com.example.notepractice
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.util.*
class MainActivity : AppCompatActivity(), NoteClickInterface, NoteClickDeleteInterface {
lateinit var viewModel: NoteViewModel
lateinit var notesRV: RecyclerView
lateinit var addFAB: FloatingActionButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
notesRV = findViewById(R.id.RVNotes)
addFAB = findViewById(R.id.FABAddNote)
notesRV.layoutManager = LinearLayoutManager(this)
val noteRVAdapter = NoteRVAdapter(this, this, this)
notesRV.adapter = noteRVAdapter
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(NoteViewModel::class.java)
/*
viewModel.allNotes.observe(this, Observer { list ->
list?.let {
noteRVAdapter.updateList(it)
}
})
addFAB.setOnClickListener {
val intent = Intent(this#MainActivity, AddEditNoteActivity::class.java)
startActivity(intent)
this.finish()
}
*/
}
override fun onNoteClick(note: Note) {
val intent = Intent(this#MainActivity, AddEditNoteActivity::class.java)
intent.putExtra("noteType", "Edit")
intent.putExtra("noteTitle", note.noteTitle)
intent.putExtra("noteDescription", note.noteDescription)
intent.putExtra("noteId", note.id)
startActivity(intent)
}
override fun onDeleteIconClick(note: Note) {
viewModel.deleteNote(note)
Toast.makeText(this, "${note.noteTitle} Deleted", Toast.LENGTH_LONG).show()
}
}
(ViewModel)
package com.example.notepractice
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class NoteViewModel(application: Application): AndroidViewModel(application) {
val allNotes: LiveData<List<Note>>
val repository: NoteRepository
init {
val dao = NoteDatabase.getDatabase(application).getNotesDao()
repository = NoteRepository(dao)
allNotes = repository.allNotes
}
fun deleteNote (note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.update(note)
}
fun addNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
}
I'd like to end my question post with an actual question, but I am very inexperienced and cannot specify the problem. What would be the correct way to set up a ViewModel in Android with Kotlin?
Try initialising NoteViewModel like this inside your Activity.
private val viewModel: NoteViewModel by lazy {
ViewModelProvider(this).get(NoteViewModel::class.java)
}
I'm trying to call the await() function in the
bookList = bookViewModel.getBookList().await()
in the Main Activity but it gives the error in the header.
Main Activity
#AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val bookViewModel: BookViewModel by viewModels()
private var bookList : BookList? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GlobalScope.launch(Dispatchers.IO) {
bookList = bookViewModel.getBookList().await()
}
setContent {
LOTRAppTheme {
}
}
}
}
ViewModel
package com.example.lotrapp
import androidx.lifecycle.ViewModel
import com.example.lotrapp.models.BookList
import com.example.lotrapp.repository.BookRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
#HiltViewModel
class BookViewModel #Inject constructor(
private val repository: BookRepository
) : ViewModel() {
suspend fun getBookList() : BookList? {
return repository.getBookList()
}
}
Repository
package com.example.lotrapp.repository
import com.example.lotrapp.models.BookList
import com.example.lotrapp.network.RetrofitApi
import javax.inject.Inject
class BookRepository #Inject constructor(
private val retrofitApi: RetrofitApi
) {
suspend fun getBookList() : BookList?
{
return retrofitApi.getBookList().body()
}
}
Api
package com.example.lotrapp.network
import com.example.lotrapp.models.BookList
import retrofit2.Response
import retrofit2.http.GET
interface RetrofitApi {
#GET("book")
suspend fun getBookList() : Response<BookList>
}
Gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
id("dagger.hilt.android.plugin")
id("kotlin-kapt")
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.lotrapp"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
def compose_version = "1.0.2"
def lifecycle_version = "2.3.1"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
// Annotation processor
kapt("androidx.lifecycle:lifecycle-compiler:$lifecycle_version")
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
implementation 'androidx.activity:activity-compose:1.3.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Hilt
implementation("com.google.dagger:hilt-android:2.38.1")
kapt("com.google.dagger:hilt-android-compiler:2.38.1")
//Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2")
}
kapt {
correctErrorTypes true
}
First I want to pull the list from the api and then show it in the UI with a Composable function (with LazyColumn) in setContent. It is enough to solve this error, but if you have better code suggestions, I would appreciate it. Thank you!
It doesn't really seem you need to invoke await() there. getBookList() returns BookList? directly, so just remove await() and it should be fine.
Additionally, you said you need to use this bookList in setContent. In that case you need to move setContent into launch block, below getBookList(). Right now setContent really executes before bookList is acquired. It is hard to provide more details without the full contents of setContent.
as I am newbie I couldnt upload images rather I wrote the code required
I was trying to implement firebase sign in activity but on running the app
i am getting app is not responding and app does not opens
My app on running keeps showing "app keeps stopping"
//here is the sign in activity
package com.example.dummymedia
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ProgressBar
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
#Suppress("DEPRECATION")
class SignInActivity : AppCompatActivity() {
private val RC_SIGN_IN: Int = 123
private lateinit var googleSignInClient:GoogleSignInClient
private lateinit var auth :FirebaseAuth
private val TAG ="SignInActivity Tag"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
auth = Firebase.auth
findViewById<Button>(R.id.SignInButton).setOnClickListener {
signIn()
}
}
private fun signIn(){
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
handlesignInresult(task)
}
}
private fun handlesignInresult(completedTask: Task<GoogleSignInAccount>?) {
try {
val account =
completedTask?.getResult(ApiException::class.java)!!
Log.d(TAG,"firebaseAuthWithGoogle:"+account.id)
firebaseAuthWithGoogle(account.idToken!!)
}catch (e:ApiException){
Log.w(TAG,"signInResult:failed code ="+e.statusCode)
}
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential =GoogleAuthProvider.getCredential(idToken,null)
findViewById<Button>(R.id.SignInButton).visibility = View.GONE
findViewById<ProgressBar>(R.id.progress_Bar).visibility = View.GONE
GlobalScope.launch(Dispatchers.IO) {
val auth = auth.signInWithCredential(credential).await()
val firebaseUser = auth.user
withContext(Dispatchers.Main){
updateUI(firebaseUser)
}
}
}
private fun updateUI(firebaseUser: FirebaseUser?) {
if (firebaseUser!=null){
val mainActivityIntent =Intent(this,MainActivity::class.java)
startActivity(mainActivityIntent)
finish()
}else{
findViewById<Button>(R.id.SignInButton).visibility = View.VISIBLE
findViewById<ProgressBar>(R.id.progress_Bar).visibility = View.GONE
}
}
}
// Androidmanifest.xml
here I moved the launcher to the sign in activity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dummymedia">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.DummyMedia">
<activity android:name=".SignInActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
</application>
</manifest>
//project level gradle
Specified the versions of dependencies used in app level gradle
buildscript {
ext.kotlin_version = "1.5.10"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
repositories {
google()
mavenCentral()
// Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
} ext
{
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.4.1'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
//app level gradle
defined the dependencies here for firebase etc
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.gms.google-services'
id 'kotlin-kapt'
}
android
{
compileSdkVersion 30
defaultConfig {
applicationId "com.example.dummymedia"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-
rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation
"androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
/* coroutines support for firebase operations */
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.1.0')
implementation 'com.google.firebase:firebase-firestore'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:7.1.1'
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation 'com.google.firebase:firebase-firestore:23.0.1'
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}
please help me, I trying make an application with phone authentication with firebase. I have activated the phone sign-in method
and this is my app gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.lumbung_inovasi.policehealthcare"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
buildConfigField("String", "BASE_API", '"http://ludes.in:5001/"')
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
// To inline the bytecode built with JVM target 1.8 into
// bytecode that is being built with JVM target 1.6. (e.g. navArgs)
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "androidx.fragment:fragment:1.2.5"
implementation 'androidx.navigation:navigation-fragment:2.2.2'
implementation 'androidx.navigation:navigation-ui:2.2.2'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.firebase:firebase-core:17.4.3'
implementation 'com.google.firebase:firebase-auth:19.3.1'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'
implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.alahammad:android-OTP-View:1.0.2'
// Retrofit & OkHttp
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation('com.facebook.stetho:stetho-okhttp3:1.5.1') {
exclude group: 'com.facebook.stetho'
}
}
I trying to create OTP layout with fragment, and I using sms catch library to be able read new message with OTP code. this is my OTP fragment code
class OtpFragment : Fragment(), OTPListener, OnSmsCatchListener<String> {
private lateinit var smsCatcher: SmsVerifyCatcher
private lateinit var phoneAuth: FirebaseAuth
private var mResendToken: ForceResendingToken? = null
private var mVerificationId: String = ""
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
otp.setOnOtpFinished(this)
phoneAuth = FirebaseAuth.getInstance()
smsCatcher = SmsVerifyCatcher(activity, this)
val phoneNumber = "+62 85157233868"
requestOTP(phoneNumber)
resend_button.setOnClickListener {
resendOTPCode(phoneNumber)
}
}
private fun requestOTP(phoneNumber: String){
PhoneAuthProvider.getInstance().verifyPhoneNumber(phoneNumber, 60, TimeUnit.SECONDS, this.requireActivity(), callbacks())
}
private fun callbacks(): OnVerificationStateChangedCallbacks {
return object : OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
Log.e("onVerificationCompleted", "${phoneAuthCredential.smsCode}")
phoneAuth.signInWithCredential(phoneAuthCredential).addOnCompleteListener {
if (it.isSuccessful){
Log.e("sign-in", "berhasil")
} else{
Log.e("sign-in", "${it.result}")
}
}
}
override fun onVerificationFailed(e: FirebaseException) {
if (e is FirebaseAuthInvalidCredentialsException) {
Log.e("invalidCredential", e.toString())
} else if (e is FirebaseTooManyRequestsException) {
Log.e("out of quota", e.toString())
}
}
override fun onCodeAutoRetrievalTimeOut(s: String) {
super.onCodeAutoRetrievalTimeOut(s)
Log.e("", s)
}
override fun onCodeSent(
verificationId: String,
forceResendingToken: ForceResendingToken
) {
super.onCodeSent(verificationId, forceResendingToken)
Log.e("code-sent", "onCodeSent:$verificationId")
mVerificationId = verificationId
mResendToken = forceResendingToken
}
}
}
private fun signInWithCredential(credential: PhoneAuthCredential){
phoneAuth.signInWithCredential(credential)
.addOnCompleteListener {
val intent = Intent(activity, MainActivity::class.java)
startActivity(intent)
activity?.overridePendingTransition(0,0)
}
.addOnFailureListener {
Log.e("login-fail", "${it.message}")
}
}
private fun resendOTPCode(phoneNumber: String){
if(mResendToken != null) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber,
120,
TimeUnit.SECONDS,
this.requireActivity(),
callbacks(),
mResendToken
)
Toast.makeText(activity, "code otp dikirim ulang", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_otp, container, false)
}
override fun otpFinished(p0: String?) {
Toast.makeText(activity, "otp finish $p0", Toast.LENGTH_SHORT).show()
p0?.let {
val credential = PhoneAuthProvider.getCredential(mVerificationId, it)
signInWithCredential(credential)
}
}
override fun onSmsCatch(p0: String?) {
Toast.makeText(activity, "sms catch $p0", Toast.LENGTH_SHORT).show()
}
}
for information, I using xiaomi redmi note 7 with internet connection and sim card is strill active
I'm trying to build an upload application modeled off this tutorial: https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#4
I'm setting a breakpoint on line 29 (where I've commented "I never reach this breakpoint. Why not?"). Why don't I reach this breakpoint when I click on the button?
MainActivity.kt
package com.example.uploadwithprogresssimple
import android.arch.lifecycle.*
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.widget.TextView
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModel = ViewModelProviders.of(this)
.get(MainViewModel::class.java)
val scheduler: TextView = findViewById(R.id.scheduleUpload)
val rootLayout: ConstraintLayout = findViewById(R.id.rootLayout)
scheduler.setOnClickListener {
viewModel.uploadVideo("/foobar/abc/def")
}
viewModel.status.observe( this, Observer {
// I never reach this breakpoint. Why not?
if (it != null) {
var size = it.size
Snackbar.make(rootLayout, "Size of video upload: ${size}", Snackbar.LENGTH_SHORT).show()
}
})
}
}
data class VideoAsset(private val filename: String)
class MainViewModel : ViewModel() {
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
private val _status = MutableLiveData<ArrayList<VideoAsset>>()
val status: LiveData<ArrayList<VideoAsset>>
get() = _status
override fun onCleared() {
super.onCleared()
uiScope.cancel()
}
fun uploadVideo(filename: String) {
uiScope.launch {
delay(1_000)
_status.value?.add( VideoAsset( filename) )
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rootLayout"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Schedule upload"
android:id="#+id/scheduleUpload"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
The app/build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.uploadwithprogresssimple"
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
def kotlinCoroutines = "1.1.0"
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutines"
}
In this case breakpoint is not reached because setValue(T) method of LiveData object is not called. Calling setValue(T) results in the observers calling their onChanged() method. Try to change your code to call setValue(T) method, i.e.:
val list = _status.value ?: arrayListOf<VideoAsset>()
list.add(VideoAsset(filename))
_status.value = list
Note: setValue(T) in Kotlin is replaced with property assigning: _status.value = list instead of _status.setValue(list)