I am enrolled in online CBT and learning Kotlin for android programming. The video tutes were made in 2017 and I got codes of the apps that were made in the to the tutorial series. I have followed every step till I connect my app with Firebase and even entered sample user data in Authentication and set Usage Rules to public, but to my surprise same Kotlin code which was shown to be working flawlessly in video tutorials does not work for me.
Then I tried sample LoginActivity.kt and RegisterActivity.kt codes from github, even those codes does not work. Please look at my codes and help me sort out this issue.
When I click on loginBtn the app crashes and not data is sent to Firebase. Logcat shows following error:
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.paramlowe.mypg2. Make sure to call
FirebaseApp.initializeApp(Context) first.
at com.google.firebase.FirebaseApp.getInstance(SourceFile:218)
at com.google.firebase.auth.FirebaseAuth.getInstance(Unknown Source:1)
at com.punjabweb.myapp.LoginActivity.loginUser(LoginActivity.kt:50)
at
com.punjabweb.myapp.LoginActivity.access$loginUser(LoginActivity.kt:25)
at
com.punjabweb.myapp.LoginActivity$onCreate$2.onClick(LoginActivity.kt:43)
and my kotlin code for LoginActivity.kt is here below:
package com.punjabweb.myapp2
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.widget.Button
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth
import kotlinx.android.synthetic.main.activity_login.*
class LoginActivity : AppCompatActivity() {
//Firebase references
private var mAuth: FirebaseAuth? = null
// FirebaseApp.initializeApp(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
val loginBtn = findViewById<View>(R.id.btnLogin) as Button
loginBtn.setOnClickListener {
loginUser()
}
}
private fun loginUser() {
mAuth = FirebaseAuth.getInstance()
val email = etEmail?.text.toString()
val password = etPassword?.text.toString()
if (TextUtils.isEmpty(email) && TextUtils.isEmpty(password)) {
Toast.makeText(this, "Enter all details", Toast.LENGTH_SHORT).show()
} else {
mAuth!!.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with signed-in user's information
var firebasUser = FirebaseAuth.getInstance().currentUser!!
// updateUI()
} else {
// If sign in fails, display a message to the user.
Toast.makeText(
this#LoginActivity, "Authentication failed.",
Toast.LENGTH_SHORT
).show()
}
}
}
fun updateUI() {
val intent = Intent(this#LoginActivity, MainActivity::class.java)
// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
}
}
}
You need to enable the firebase email authentication in the console. Seems like your code is ok in the first look.
This could potentially be cause because you don't have the google-services plugin at the end of app gradle:
dependencies {
....
}
apply plugin: 'com.google.gms.google-services'
Related
I want to enable my users to set certain global colors when using the app. Therefor I have created a 'dynamicVariables.css' file:
:root {
--my-color: violet;
}
It is imported in 'global.scss' file:
#import "./theme/dynamicVariables.css";
Also, I've added a colorpicker on one page and I can set the --my-color variable fine from there.
onColorChange(data: any) {
document.documentElement.style.setProperty('--my-color', data);
}
Just when closing the app on my device (I've deployed it with ionic capacitor run android), it resets the css variable, because when I run it again the color is back to its default value.
I'm pretty sure, I have a general misconception here and would be grateful for some clarification. I'm generally new to web development and would be grateful for any help.
Thanks in advance.
just like how Mustafa explained in comments, you need to make these changes outside app "runtime" and in the device's memory, that would stay there even after the app (whether web or native) is closed. for example you can use ionic storage and save your data with keys and values same as your css keys, and load it up whenever the app opens.
Thanks to the responds, I was able to solve the problem with the help of Ionic Storage.
First, I created a Storage Service:
import { Storage } from '#ionic/storage-angular';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class StorageService {
private _storage: Storage | null = null;
constructor(private storage: Storage) {
}
async init() {
const storage = await this.storage.create();
this._storage = storage;
}
public set(key: string, value: any) {
this._storage?.set(key, value);
}
public get(key: string) {
return this._storage?.get(key);
}
}
When starting the app, I run the following code in the app.component.ts
async ngOnInit() {
await this.storageService.init();
let storedPathologicalColor = await this.storageService.get('--my-color');
if (storedPathologicalColor == null)
document.documentElement.style.setProperty('--my-color', getComputedStyle(document.documentElement).getPropertyValue('--my-color'))
else
document.documentElement.style.setProperty('--my-color', storedPathologicalColor);
}
It is important to init() the service from outside. When setting a new css variable, I also set a new key/value pair to the Storage.
Thanks again.
I have an app already that I was able to build completely with SwiftUI.
I was using Firebase for authentication and notifications using Cloud Functions.
Now with the new SwiftUI App->Scene->View construct, I am unable to add the setup to my app.
For example -> The initial FirebaseApp.configure() would initially go in didFinishLaunchingWithOptions in AppDelegate, now I am at a loss of where to add this configuration.
Same goes with setting up remote notifications.
PS: Please comment if more details/code of the previous app is required. I did not add any code, cause I felt it was unnecessary.
There are three approaches for initialising third part frameworks in the new SwiftUI life cycle:
Using the old life cycle model
You can still use the old life cycle model:
Option 1: Use the UIKit App Delegate life cycle
When creating a new SwiftUI project, you can choose the old life cycle model. This will create an AppDelegate and a SceneDelegate as before. Not as fancy as using SwiftUI all the way, I admit - but definitely the easiest and most straightforward way.
Using the new life cycle model
If you want to use the new life cycle model, use either one of the following approaches.
Option 2: Use the App's initialiser
You can override the default initialiser of your App class, like this:
import SwiftUI
import Firebase
#main
struct SO62626652_InitialiserApp: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Option 3: Use # UIApplicationDelegateAdaptor
In you App class, define a property that holds a reference to your AppDelegate, and let SwiftUI inject the AppDelegate using the # UIApplicationDelegateAdaptor property wrapper, like this:
import SwiftUI
import Firebase
#main
struct SO62626652_AppDelegateAdaptorApp: App {
#UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}
Found the answer on the link below:
hackingWithSwift
The code from the page is below:
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("Your code here")
FirebaseApp.configure()
return true
}
}
And inside the App
we need to add the below line:
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate.
The explanation is on the link.
I wanted to user firestore in my unity proyect, so I did as in the documentation. Notice that I also do db = FirebaseFirestore.DefaultInstance;.
I put the firebase starting code in a trial monobehviour in of my scene, in which I wanted to make some database query trials.
Firebase.FirebaseApp app;
void Start() {
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available) {
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
app= Firebase.FirebaseApp.DefaultInstance;
Debug.LogError("FirebaseApp succesfully created");
// Set a flag here to indicate whether Firebase is ready to use by your app.
} else {
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
db = FirebaseFirestore.DefaultInstance;
}
Every time I stopped my app and re-played in the editor, unity freezed, and I had to kill the process and restart unity.
Since I commented out the: app= Firebase.FirebaseApp.DefaultInstance;
to: //app= Firebase.FirebaseApp.DefaultInstance; as I only wanted to use the database, everything is going fine.
Am I doing something wrong? Does it make sense that due to some mistake unity hangs after re-play (first play works).
On the other hand I dont understand why in the docs the code advices to store the FirebaseApp in a variable if the FirebaseApp class has got an static instance getter: public static FirebaseApp DefaultInstance { get; }
Thanks for any comment.
I'm trying to implement App Check in my Flutter app for Android and have followed the flutterfire documentation. I have already complete the installation part outlined here: https://firebase.flutter.dev/docs/app-check/overview
Now I am following this documentation for usage: https://firebase.flutter.dev/docs/app-check/usage
So I have added the await FirebaseAppCheck.instance.activate(webRecaptchaSiteKey: 'recaptcha-v3-site-key'); to my Main method, right after the call to initialize firebase.
Now I need to enable debugging with the App Check and the documentation says I should add this dependency to my app/build.gradle file: implementation 'com.google.firebase:firebase-appcheck-debug:16.0.0-beta01' and add the following code snippet to my MainActivity.java onCreate method:
import com.google.firebase.appcheck.FirebaseAppCheck;
FirebaseApp.initializeApp(/*context=*/ this);
FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
firebaseAppCheck.installAppCheckProviderFactory(DebugAppCheckProviderFactory.getInstance());
Which I have tried to do by creating the MainActivity.java with the following command in my project root folder: flutter create -a java .
So my MainActivity.java looks like this:
import io.flutter.embedding.android.FlutterActivity;
import com.google.firebase.appcheck.FirebaseAppCheck;
public class MainActivity extends FlutterActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirebaseApp.initializeApp(/*context=*/ this);
FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance());
}
}
When trying to run the app in debug mode I get the this error: Execution failed for task ':app:compileDebugJavaWithJavac'.
What am I missing? Have seen other posts with the same problem but no solution.
This should be your main.dart
import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await FirebaseAppCheck.instance.activate();
}
Note: await FirebaseAppCheck.instance.activate(); does not have webRecaptchaSiteKey: 'recaptcha-v3-site-key' for Android/iOS App
This should be your MainActivity.kt
package com.example.app // your package
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.FirebaseAppCheck
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory
class MainActivity: FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/example"
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
FirebaseApp.initializeApp(/*context=*/this)
val firebaseAppCheck = FirebaseAppCheck.getInstance()
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance()
)
}
}
}
Thank to Firebase the user can logged with the help of G+, Facebook or Twitter. When they are logged, everything is fine.
When the Android app is closed and re-opened, how to reenable the previous succeed logged user with the Firebase API. It is not explained neither in the app demo or in the documentation.
For exemple for Facebook, the sdk seems to save the token, that 's why the button is at connected state (showing that you can disconnect). But what about Firebase and for other authentication systems.
Thanks to the #Frank-van-Puffelen answer, I had some trials until I get something relevant (at least for me : comment are welcome to improve).
I have based my OAuth architecture into 3 mains components :
fdsfds
One single AuthStateListener that is located in the Application.
One Utils Singleton OAuthManager that deal with all authentication process
One or Many Activities that deals with Authentification user interaction (Signin Buttons and so on)
Application Class
FacebookSdk.sdkInitialize(this);
Firebase.setAndroidContext(this);
Firebase.getDefaultConfig().setLogLevel(Logger.Level.DEBUG);
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
// create a partialUser from authData
OAuthManager.getDefault().setAuthenticatedUser(authData);
// fetch, merge and save back the partialUser with server registerUser.
OAuthManager.getDefault().startFetchingUserInfo();
} else {
// user is not logged in
// Try to retrieve the user from Facebook SDK
// Try to retrieve the user from "Token and Id save in Android Preferences (in case of issue, or cache reset from Firebase))
// In retrieve is not possible, clean auth data
OAuthManager.getDefault().retrieveOAuth(MilleZimU.getInstance());
}
}
});
OAuthManager
Here is every services that deal with authentication (part has been copy from the Firebase dedicated demo activity)
SignInActivity
Here only remain the part that deal with UI interaction.
Retreiving ?
I'm not sure this is necessary, but case to case (maybe due to crash or update of the app), authentication status where different from Firebase|Prefs|FacebookSdk. I will see with time.
You'll need to add a AuthStateListener. This is described in the Firebase documentation on Monitoring Authentication. From there:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
} else {
// user is not logged in
}
}
});
For anything related to Firebase Authentication on Android, the dedicated demo app is a great next stop. But be sure to first read the documentation, they're not half bad as far as docs go.
Create a BaseActivity class and make sure all other Activities in the app extends that class. The use 'instanceOf' to send user to LoginActivity if authData is null from AuthListener.
package com.mabiri.mabiristores;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.firebase.client.AuthData;
import com.firebase.client.Firebase;
import com.mabiri.mabiristores.login.CreateAccount2Activity;
import com.mabiri.mabiristores.login.CreateAccountActivity;
import com.mabiri.mabiristores.login.LoginActivity;
import com.mabiri.mabiristores.login.MapsActivity;
import com.mabiri.mabiristores.utils.Utils;
public class BaseActivity extends AppCompatActivity {
protected Firebase.AuthStateListener mAuthListener;
protected Firebase mFirebaseRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseRef = new Firebase(YOUR_FIREBASE_URL);
if (!((this instanceof LoginActivity) || (this instanceof CreateAccountActivity)
|| (this instanceof CreateAccount2Activity) || (this instanceof MapsActivity))) {
mAuthListener = new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
/* The user has been logged out */
if (authData == null) {
//Stop services and clear sharedPreferences if any
/*Take user to login screen*/
takeUserToLoginScreenOnUnAuth();
}
}
};
mFirebaseRef.addAuthStateListener(mAuthListener);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.menu_base, menu);
return true;
}
private void takeUserToLoginScreenOnUnAuth() {
/** Move user to LoginActivity, and remove the backstack */
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
protected void logout() {
/**Unauthenticate user from firebase*/
mFirebaseRef.unauth();
}
/**
* Show error toast to users
*/
protected void showErrorToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
Yup I have struggle with this as well, but a quick update on this issue, you cannot use the (and please correct me if i'm wrong):
Firebase ref
anymore, what you should do is declare as a global
private FirebaseAuth mAuth;
and then use this object on the listener:
mAuth = FirebaseAuth.getInstance();
and only after that you can use the listener
mAuth.addAuthStateListener(mAuthListener);