My app crashes on starting it (basically any activity with firebase code) after adding firebase authentication
This is the logcat
2022-07-14 20:17:21.538 15482-15482/com.example.flimer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.flimer, PID: 15482
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.flimer/com.example.flimer.SignUp}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3086)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3318)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:113)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:71)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2044)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:226)
at android.app.ActivityThread.main(ActivityThread.java:7212)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:956)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:170)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:682)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:848)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:815)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:640)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:259)
at com.example.flimer.SignUp.<init>(SignUp.kt:15)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3074)
This is the code for the splashscreen
class Startscreen : AppCompatActivity() {
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_startscreen)
auth = Firebase.auth
val user = auth.currentUser
if (Build.VERSION.SDK_INT < 16) {
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
}
if (user != null){
Handler().postDelayed({
val intent = Intent(this#Startscreen, MainActivity::class.java)
startActivity(intent)
finish()
}, 2000)
}else{
Handler().postDelayed({
val intent = Intent(this#Startscreen, SignUp::class.java)
startActivity(intent)
finish()
},2000)
}
}
This is the crash happening in my sign up screen on starting
class SignUp : AppCompatActivity() {
private lateinit var etEmail: String
private lateinit var etPass: String
private lateinit var etPass2: String
private lateinit var btn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_up)
etEmail = findViewById<EditText>(R.id.et_email).text.toString().trim { it <= ' ' }
etPass = findViewById<EditText>(R.id.pass).text.toString().trim { it <= ' ' }
etPass2 = findViewById<EditText>(R.id.et_pass2).text.toString().trim { it <= ' ' }
btn = findViewById(R.id.btn_create)
btn.setOnClickListener {
dialog()
if (isValid(etEmail, etPass, etPass2)){
signUp(etEmail, etPass)
}
}
}
private fun isValid(email: String, pass: String,pass2: String ): Boolean{
return if (email.isEmpty() && pass.isEmpty()){
Toast.makeText(this#SignUp, "Fill in the blanks", Toast.LENGTH_SHORT).show()
false
}else if(pass != pass2){
Toast.makeText(this#SignUp, "Passwords do not match", Toast.LENGTH_SHORT).show()
false
}else{
true
}
}
private fun signUp(email: String, pass: String){
var auth: FirebaseAuth = Firebase.auth
auth.createUserWithEmailAndPassword(email,pass).addOnCompleteListener {
dismiss()
if (it.isSuccessful){
Toast.makeText(this#SignUp, "Success",Toast.LENGTH_SHORT ).show()
}else{
Toast.makeText(this#SignUp, it.exception!!.message, Toast.LENGTH_SHORT).show()
}
}
}
private fun dialog(){
val dialog = Dialog(this)
dialog.setContentView(R.layout.custom_dialog)
dialog.show()
}
private fun dismiss(){
Dialog(this).dismiss()
}
}
The auth variable is initialized as follows
auth = FirebaseAuth.getInstance()
And not how you are doing
auth = Firebase.auth
Related
I developed an application to get NFC adapter using NfcAdapter.getDefaultAdapter(this) function. But it gives NullPointerException - NfcAdapter.getDefaultAdapter(this) must not be null.
class TappingActivity : BaseActivity() {
private lateinit var mNfcAdapter: NfcAdapter
private lateinit var mFusedLocationClient: FusedLocationProviderClient
private lateinit var mBroadcastReceiver: BroadcastReceiver
private lateinit var mAdapter: RecyclerViewAdapter<SecurityPoint, ViewHolder>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tapping)
ButterKnife.bind(this)
setSupportActionBar(toolbar)
savedInstanceState?.let {
lastLoggedPremisesID = it.getInt("lastLoggedPremisesID")
}
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
if (!mNfcAdapter.isEnabled) {
snack(getString(R.string.str_nfc_disabled), Snackbar.LENGTH_INDEFINITE, R.color.error)
}
}
override fun onResume() {
super.onResume()
setupForegroundDispatch()
}
override fun onPause() {
super.onPause()
stopForegroundDispatch()
}
override fun onDestroy() {
super.onDestroy()
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver)
}
private fun setupForegroundDispatch() {
val intent = Intent(this, TagDetection::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
val intentFilter = IntentFilter()
intentFilter.addAction(NfcAdapter.ACTION_TAG_DISCOVERED)
intentFilter.addCategory(Intent.CATEGORY_DEFAULT)
val techList = arrayOf<Array<String>>()
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, arrayOf(intentFilter), techList)
}
private fun stopForegroundDispatch() {
mNfcAdapter.disableForegroundDispatch(this)
}
}
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.antlergroup.patrolsystem, PID: 11333
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.antlergroup.patrolsystem/com.antlergroup.patrolsystem.ui.SecurityPointRegistrationActivity}: java.lang.NullPointerException: NfcAdapter.getDefaultAdapter(this) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4076)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2473)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8349)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.lang.NullPointerException: NfcAdapter.getDefaultAdapter(this) must not be null
at com.antlergroup.patrolsystem.ui.SecurityPointRegistrationActivity.onCreate(SecurityPointRegistrationActivity.kt:72)
at android.app.Activity.performCreate(Activity.java:8085)
at android.app.Activity.performCreate(Activity.java:8073)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3870)
You need to define NfcManager first then you can call the getDefaultAdapter method. Please refer to the code snippet.
private var mNfcAdapter: NfcAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tapping)
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
mNfcAdapter = manager.getDefaultAdapter();
}
For more information, you can refer to this link
I'm new to Kotlin and I'm trying to send two strings from two textViews in one activity to another using intents. However, I'm getting this error when I run the function load.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.pdm_2021_i_p1_project1, PID: 18672
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.pdm_2021_i_p1_project1/com.example.pdm_2021_i_p1_project1.PlayActivity}: java.lang.IllegalStateException: intent must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3365)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: intent must not be null
at com.example.pdm_2021_i_p1_project1.PlayActivity.getWord(PlayActivity.kt:119)
at com.example.pdm_2021_i_p1_project1.PlayActivity.<init>(PlayActivity.kt:21)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Here's my code from the activity receiving the strings
class PlayActivity : AppCompatActivity() {
//Variable Declarations
private val lives : Int = 4
private var fails : Int = 0
private var correctGuesses = mutableSetOf<Char>()
private var guesses = mutableSetOf<Char>()
private val word = getWord().toLowerCase(Locale.ROOT)
private val clue = getClue().toLowerCase(Locale.ROOT)
private val letters = word.toLowerCase(Locale.ROOT).toCharArray().toHashSet()
private val txtArray = arrayOfNulls<TextView>(word.length)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_play)
btnCheck.setOnClickListener{(checkWord())}
createTxtViews()
txvClue.text = clue.toUpperCase(Locale.ROOT)
txvLives.text = "❤❤❤❤"
}
private fun checkWord(){
val character = txtPlayAddLetter.text.toString().toLowerCase(Locale.ROOT)
if (txtPlayAddLetter.text.isNotEmpty()){
if (word.contains(txtPlayAddLetter.text.toString().toLowerCase(Locale.ROOT))) {
correctGuesses.add(character[0])
guesses.add(character[0])
txvGuessed.text = guesses.toString().toUpperCase(Locale.ROOT)
txvTest.text = letters.toString()
showLetters()
txtPlayAddLetter.text.clear()
checkGameState()
}
else
{
fails++
guesses.add(character[0])
txvGuessed.text = guesses.toString().toUpperCase(Locale.ROOT)
txtPlayAddLetter.text.clear()
val hearts = txvLives.text.dropLast(1)
txvLives.text = hearts
when (fails) {
1 -> {frame1.isVisible = false
frame2.isVisible = true}
2 -> {frame2.isVisible = false
frame3.isVisible = true}
3 -> {frame3.isVisible = false
frame4.isVisible = true}
4 -> {frame4.isVisible = false
frame5.isVisible = true}}
if (fails == lives)
{
showDefeat()
}
}
}
else
{
Toast.makeText(this#PlayActivity, "Please enter a letter :)", Toast.LENGTH_LONG).show()
}
}
private fun showDefeat(){
val intent = Intent(this, DefeatActivity::class.java)
finish()
startActivity(intent)
}
private fun showVictory(){
val intent = Intent(this, VictoryActivity::class.java)
finish()
startActivity(intent)
}
private fun createTxtViews(){
val lLayout = findViewById<View>(R.id.txtPlayGuessed) as LinearLayout
for (i in word.indices) {
txtArray[i] = TextView(this)
txtArray[i]?.id = i
txtArray[i]?.setTextColor(resources.getColor(R.color.white))
txtArray[i]?.hint = " _ "
txtArray[i]?.setHintTextColor(resources.getColor(R.color.white))
txtArray[i]?.textSize = 25F
lLayout.addView(txtArray[i])
txtArray[i]?.isVisible = true
}
}
private fun showLetters(){
val str = txtPlayAddLetter.text.toString().toLowerCase(Locale.ROOT)
for (i in word.indices){
if (txtPlayAddLetter.text.single().toLowerCase() == word[i]){
txtArray[i]?.text = " ".plus(str.toUpperCase(Locale.ROOT)).plus(" ")
}
}
}
private fun checkGameState(){
if (correctGuesses == letters){
showVictory()
finish()
}
}
fun getWord(): String{
val bundle=intent.extras
val setword= bundle?.get("setword")
return getString(R.string.setwordplay,setword)
}
fun getClue(): String{
val bundle = intent.extras
val setclue = bundle?.get("setclue")
return getString(R.string.setwordplay,setclue)
}}
And here's my code from the activity sending the strings
fun load(){
val intent = Intent(this, PlayActivity::class.java)
intent.putExtra("setword", editTextTypeAWord.text.toString())
intent.putExtra("setclue", editTextHint.text.toString())
startActivity(intent)
}
You are trying to initialise the val with data from Intent. In PlayActivity, the init{} block and property initialisations run before onCreate().
To work around this issue you could try:
class PlayActivity : AppCompatActivity() {
companion object {
const val ARG_WORD = "word"
const val ARG_CLUE = "clue"
}
private lateinit var word: String
private lateinit var clue: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
word = intent.getStringExtra(ARG_WORD) ?: throw IllegalArgumentException("Word was not supplied")
clue = intent.getStringExtra(ARG_CLUE) ?: throw IllegalArgumentException("Clue was not supplied")
}
}
Call with:
val intent = Intent(this, PlayActivity::class.java).apply {
putExtra(PlayActivity.ARG_WORD, "giraffe")
putExtra(PlayActivity.ARG_CLUE, "long neck")
}
startActivity(intent)
Also, remember to refactor other properties that rely on word and clue to use either functions or getters, otherwise you'll run into UninitializedPropertyAccessException.
What using getters does is that every time you call the property the get()-portion is calculated. Since you're using the properties after onCreate(), your lateinit properties should already have been initialised from the intent you've received!
class PlayActivity : AppCompatActivity() {
companion object {
const val ARG_WORD = "word"
const val ARG_CLUE = "clue"
}
private lateinit var word: String
private lateinit var clue: String
private val letters: HashSet<Char>
get() = word.toLowerCase(Locale.ROOT).toCharArray().toHashSet()
private val txtArray: Array<TextView?>
get() = arrayOfNulls<TextView>(word.length)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
word = intent.getStringExtra(ARG_WORD) ?: throw IllegalArgumentException("Word was not supplied")
clue = intent.getStringExtra(ARG_CLUE) ?: throw IllegalArgumentException("Clue was not supplied")
}
}
I highly recommend you to read this: https://kotlinlang.org/docs/properties.html
val intent = Intent(this, PlayActivity::class.java).apply {
putExtra("setword", message)
}
startActivity(intent)
try this
private fun showVictory(){
val intent = Intent(this, VictoryActivity::class.java)
startActivity(intent)
finish()
}
use like this
intent?.getStringExtra("setword") ?: ""
intent?.getStringExtra("setclue") ?: ""
try this way
fun getWord(): String{
val setword= intent.getStringExtra("setword")
return getString(R.string.setwordplay,setword)
}
fun getClue(): String{
val setclue = intent.getStringExtra("setclue")
return getString(R.string.setwordplay,setclue)
}}
I don't really understand why logFile(and loggingProcess) are not initialized. The logcat shows that the file exists and createLogFile() method had been called when Activity was created, but when I'm trying to uploadLogs() from the Activity(using SandboxApp().uploadLogs()) it throws an exception
class SandboxApp: Application(), MyCallbacks {
companion object {
#JvmField
val TAG = SandboxApp::class.java.simpleName
}
private lateinit var loggingProcess: Process
private lateinit var logFile: File
private lateinit var fileDirectory: File
private var isLogging = false
private val formatter = SimpleDateFormat("dd-MM-yyyy_HH-mm", Locale.getDefault())
private lateinit var workManager: WorkManager
override fun onCreate() {
super.onCreate()
workManager = WorkManager.getInstance(this)
registerActivityLifecycleCallbacks(this)
}
fun createLogFile() {
val currentTime = formatter.format(Calendar.getInstance().time)
val fileName = "logs-$currentTime.log"
fileDirectory = File(filesDir.absolutePath + File.separator + "sandboxLog")
fileDirectory.mkdirs()
Log.d(TAG, "FileDir exists? $fileDirectory, ${fileDirectory.exists()}")
logFile = File(fileDirectory, fileName)
logFile.createNewFile()
Log.d(TAG, "File exists? $logFile, ${logFile.exists()}")
}
fun startLogging() {
isLogging = true
loggingProcess = Runtime.getRuntime().exec("logcat -f $logFile")
}
private fun stopLogging() {
isLogging = false
loggingProcess.destroy()
}
fun uploadLogs() {
stopLogging()
val data = Data.Builder()
.putString("file path", logFile.absolutePath)
.build()
val request = OneTimeWorkRequest.Builder(LogsWorker::class.java)
.setInputData(data)
.build()
workManager.enqueue(request)
createLogFile()
startLogging()
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
super.onActivityCreated(activity, savedInstanceState)
Log.d(TAG, "onActivityCreated method")
createLogFile()
startLogging()
}
}
This is the exception, tha same is for the loggingProcess variable
2020-08-04 15:55:51.338 8741-8741/com.example.sandboxlog E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sandboxlog, PID: 8741
kotlin.UninitializedPropertyAccessException: lateinit property logFile has not been initialized
at com.example.sandboxlog.SandboxApp.uploadLogs(SandboxApp.kt:66)
at com.example.sandboxlog.MainActivity$onCreate$2.onClick(MainActivity.kt:33)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
upd: onCreate method of MainActivity, where uploadLogs is being called
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "MainActivity created")
Thread.setDefaultUncaughtExceptionHandler(CrashHandler())
button.setOnClickListener {
// creating an exception
RequestBody.create(MultipartBody.FORM, exceptionFile!!)
}
buttonSend.setOnClickListener {
SandboxApp().uploadLogs()
}
buttonSecondActivity.setOnClickListener {
Log.d(TAG, "Starting second activity")
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
}
You shouldn't create an instance of your app class SandboxApp by yourself, it is done by the system. To have access to the instance of SandboxApp you can use ctx.applicationContext property:
val app = context.applicationContext as SandboxApp
app.uploadLogs()
So in the OnClickListener it will look like the following:
buttonSend.setOnClickListener {
val app = applicationContext as SandboxApp
app.uploadLogs()
}
Android Studio 4.0
import retrofit2.Response
import retrofit2.http.GET
interface TestRestClient {
#GET("films")
suspend fun getFilms(): Response<List<Film>>
}
suspend fun getFilms(isCustomtHandle: Boolean = false): Response<*> {
Debug.d(TAG, "getFilms: ")
suspend fun execOperation(): Response<*> = testRestClient.getFilms()
return runOperation(isCustomtHandle, ::execOperation)
}
In my ViewModel
class FilmsRxJavaViewModel(application: Application) : AndroidViewModel(application) {
companion object {
private val TAG = FilmsRxJavaViewModel::class.java.name
}
lateinit var observable: Single<List<Film>>
init {
loadData()
}
fun loadData() {
viewModelScope.launch(Dispatchers.Main) {
Debug.d(TAG, "loadData: START")
val response = TransportService.getFilms()
val isSuccessResponse = response.isSuccessful
if (isSuccessResponse) { // code >= 200 && code < 300;
val filmsList : List<Film> = response.body() as List<Film>
observable = Single.just(filmsList)
} else { // error - status (300-599) or network failure
val message = response.errorResponse.message
Debug.w(TAG, "loadData: message = $message")
}
Debug.d(TAG, "loadData: FINISH")
} // end coroutine
}
}
In my activity
class FilmsRxJavaActivity : AppCompatActivity() {
private lateinit var filmsRxJavaViewModel: FilmsRxJavaViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Debug.d(TAG, "onCreate: savedInstanceState = $savedInstanceState")
setContentView(R.layout.films_rx_java_activity)
binding = FilmsRxJavaActivityBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
val dispose = filmsRxJavaViewModel.observable
// to subscribe in IO thread
.subscribeOn(Schedulers.newThread())
// observe the task's result on the main thread
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
Debug.d(TAG, "initLogic: subscribe_filmsList(${it.size})\n$it")
}, {
Debug.e(TAG, "initLogic: error = $it")
)
}
}
But I get error when open my activity:
Error in this line:
lateinit var observable: Single<List<Film>>
Details:
07-14 10:23:51.557 D/AndroidRuntime( 6803): Shutting down VM
--------- beginning of crash
FATAL EXCEPTION: main
Process: .androidtestproject.debug, PID: 6803
java.lang.RuntimeException: Unable to start activity ComponentInfo{androidtestproject.debug/.androidtestproject.ui.activity.FilmsRxJavaActivity}: kotlin.UninitializedPropertyAccessException: lateinit property observable has not been initialized
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property observable has not been initialized
at .androidtestproject.viewmodel.FilmsRxJavaViewModel.getObservable(FilmsRxJavaViewModel.kt:26)
at .androidtestproject.ui.activity.FilmsRxJavaActivity.initLogic(FilmsRxJavaActivity.kt:54)
at .androidtestproject.ui.activity.FilmsRxJavaActivity.init(FilmsRxJavaActivity.kt:45)
at .androidtestproject.ui.activity.FilmsRxJavaActivity.onCreate(FilmsRxJavaActivity.kt:33)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
... 11 more
Exception happens inside else block because observable will still not initialized
fun loadData() {
viewModelScope.launch(Dispatchers.Main) {
Debug.d(TAG, "loadData: START")
val response = TransportService.getFilms()
val isSuccessResponse = response.isSuccessful
if (isSuccessResponse) { // code >= 200 && code < 300;
val filmsList : List<Film> = response.body() as List<Film>
observable = Single.just(filmsList)
} else { // error - status (300-599) or network failure
val message = response.errorResponse.message
Debug.w(TAG, "loadData: message = $message")
// give a value to observable when error happen .
}
Debug.d(TAG, "loadData: FINISH")
} // end coroutine
}
Hello I am getting this exception continuously on launch of app :
2019-02-18 16:33:14.735 2080-2080/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: assus.oumayma.com.firebasekotlinapp, PID: 2080
java.lang.RuntimeException: Unable to start activity ComponentInfo{assus.oumayma.com.firebasekotlinapp/assus.oumayma.com.firebasekotlinapp.MainActivity}: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process assus.oumayma.com.firebasekotlinapp. Make sure to call FirebaseApp.initializeApp(Context) first.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2725)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2786)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:173)
at android.app.ActivityThread.main(ActivityThread.java:6459)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:938)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process assus.oumayma.com.firebasekotlinapp. Make sure to call FirebaseApp.initializeApp(Context) first.
at com.google.firebase.FirebaseApp.getInstance(com.google.firebase:firebase-common##16.0.2:240)
at com.google.firebase.auth.FirebaseAuth.getInstance(Unknown Source)
at assus.oumayma.com.firebasekotlinapp.MainActivity.onCreate(MainActivity.kt:23)
at android.app.Activity.performCreate(Activity.java:6673)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
and this the code:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mAuth = FirebaseAuth.getInstance()
signOut.setOnClickListener {
view: View? -> mAuth.signOut()
startActivity(Intent(this, PhoneAuthenfication::class.java))
Toast.makeText(this, "Logged out Successfully :)", Toast.LENGTH_LONG)
.show()
}
}
override fun onStart() {
super.onStart()
if (mAuth.currentUser == null) {
startActivity(Intent(this, PhoneAuthenfication::class.java))
} else {
Toast.makeText(this, "Already Signed in :)", Toast.LENGTH_LONG).show()
}
}
}
class PhoneAuthenfication : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_phone_authenfication)
mAuth = FirebaseAuth.getInstance()
veriBtn.setOnClickListener { view: View? ->
progress.visibility = View.VISIBLE
verify()
}
authBtn.setOnClickListener { view: View? ->
progress.visibility = View.VISIBLE
authenticate()
}
}
private fun verificationCallbacks() {
mCallbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) {
progress.visibility = View.INVISIBLE
signIn(credential)
}
override fun onVerificationFailed(p0: FirebaseException?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCodeSent(verfication: String?, p1: PhoneAuthProvider.ForceResendingToken?) {
super.onCodeSent(verfication, p1)
verificationId = verfication.toString()
progress.visibility = View.INVISIBLE
}
}
}
private fun verify() {
verificationCallbacks()
val phnNo = phnNoTxt.text.toString()
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phnNo,
60,
TimeUnit.SECONDS,
this,
mCallbacks
)
}
private fun signIn(credential: PhoneAuthCredential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener { task: Task<AuthResult> ->
if (task.isSuccessful) {
toast("Logged in Successfully :)")
startActivity(Intent(this, MainActivity::class.java))
}
}
}
private fun authenticate() {
val verifiNo = verifiTxt.text.toString()
val credential: PhoneAuthCredential = PhoneAuthProvider.getCredential(verificationId, verifiNo)
signIn(credential)
}
private fun toast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
}
the build.gradle:
implementation 'com.google.firebase:firebase-auth:16.1.0'
implementation 'com.google.firebase:firebase-core:16.0.7'
You are trying to get an instance of Firebase without initialise it. Please add this line of code before you try to get an instance of Firebase:
FirebaseApp.initializeApp(this);
If you are using google service 4.1.0
classpath 'com.google.gms:google-services:4.1.0'
then update the version to
classpath 'com.google.gms:google-services:4.2.0'