I am trying to develop an app in android studio using firebase where user verifies their email address after signup. But even after verifying the email address, whenever I open the app again, it forwards me to the send email verification code page. However, if I clear app data, the same problem does not exist.
I tried using AuthStateListener (without knowing much about it) but it did not work.
here is the code that I tried. I also tried it without the authstatelistener, but the same problem continued
mAuth=FirebaseAuth.getInstance();
user=mAuth.getCurrentUser();
authStateListener=new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if(!user.isEmailVerified()){
startActivity(new Intent(HomePage.this,VerifyEmail.class));
}
}
};
It leads to the verify email page if I open it in the phone where I signed up. But after clearing the data, it does not forward me to that page.
The reason for this issue is the FirebaseUser object is cached in the app by default. That's why there is no problem when the app data is cleared. To fix this call FirebaseAuth.getCurrentUser().reload() when your app starts.
mAuth=FirebaseAuth.getInstance();
user=mAuth.getCurrentUser();
user.reload()
if(!user.isEmailVerified()){
startActivity(new Intent(HomePage.this,VerifyEmail.class));
}
Related
I have a problem with Firebase: I would like to associate an app created with Android Studio, an archive created with the room class. I followed all the instructions, inserted the .json file, inserted all dependencies in the gradle, but when I insert a new item through my app, Realtime Database doesn't update. I have updated everything, also tried with a physical device, but nothing, it doesn't work.
I followed the wizard in Android Studio but I get this error when trying to connect to Firebase:
Connection failed
Firefox cannot establish a connection with the server localhost: 56495.
The site may be unavailable or overloaded. Try again in a few moments. If no pages can be loaded, check the computer's network connection. If your computer or network is behind a firewall or proxy, make sure Firefox has permissions to access the web.
If you have Android Studio, there is a very simple way of adding Firebase Functionality without all thoses steps (it worked for me)
Go to Android Studio, then Tools > Firebase > Realtime Database
and follow the very simple steps.
It will automatically download and setup everything you need automatically, you only have to log into Firebase when asked.
Then you can upload something with following code:
DatabaseReference myRef = database.getReference("/your_path/your_key");
myRef.setValue("your_value")
And if you want to get the updates in your app then following will do:
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
// This will get called every time /your_path/your_key gets
// changed so essetially every time you change your_value
// do something. Here an example of how to get a String
String str = snapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Update
I had every activity set as SingleInstance on launch mode, which makes sense why the issue had appear. Set it as default or SingleTop and it clears out the issue.
So, I'm making an android app where there is Firebase email auth for signing in and out. There is a ProfileActivity that shows user's profile picture and other information like images, posts and etc. When that user is signed out, and another user is logged in and navigates to profileActivity, the data from the previous user appears. But if the app is closed and restarted, then everything is fine, the correct data is displayed. This sigin and signout are done simultaneously without closing the app and only then the problem seems to appear.
I've tried modifying rules in the firebase database, rechecked the signout method and didn't find any related issue.
Firebase database rules
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
sign out method
auth = FirebaseAuth.getInstance();
auth.signOut();
these methods are included too
#Override
protected void onStart() {
super.onStart();
auth.addAuthStateListener(authStateListener);
}
#Override
public void onStop(){
super.onStop();
if(authStateListener != null){
auth.removeAuthStateListener(authStateListener);
}
}
got some copy-paste code from firebaseauth tutorial to connect a client on my app with Microsoft authentication. problem is, login screen not showing
you can find the full tutorial here.
note, I did copy everything just to test connection (not including optional code, to simplify things)
the problem stats at firebaseAuth.startActivityForSignInWithProvider method. it always ends up with failure. trace show this message:
"FirebaseAuthException... There was an error while trying to get your package certificate hash."
I did everything in the tutorial including registration of my app at Microsoft and Firebase Authentication screen. I ran this code at android studio emulator and an actual device, same result
my sign in function:
public void signinToMicrosoft(Activity activity) {
OAuthProvider.Builder provider = OAuthProvider.newBuilder("microsoft.com");
Log.e(TAG,"Signing with microsoft");
Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
if (pendingResultTask != null) {
// There's something already here! Finish the sign-in for your user.
pendingResultTask
.addOnSuccessListener(
new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Log.e(TAG,"Pending Success");
// User is signed in.
// IdP data available in
// authResult.getAdditionalUserInfo().getProfile().
// The OAuth access token can also be retrieved:
// authResult.getCredential().getAccessToken().
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Pending Failed: "+e.getMessage());
// Handle failure.
}
});
} else {
Log.e(TAG,"No Pending");
// There's no pending result so you need to start the sign-in flow.
// See below.
}
firebaseAuth
.startActivityForSignInWithProvider(activity, provider.build())
.addOnSuccessListener(
new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Log.e(TAG,"Auth Success");
// User is signed in.
// IdP data available in
// authResult.getAdditionalUserInfo().getProfile().
// The OAuth access token can also be retrieved:
// authResult.getCredential().getAccessToken().
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Auth Failed: "+e.getMessage() + "\nTrace: "+ e.getClass().getCanonicalName());
// Handle failure.
}
});
}
a custom chrome tab was supposed to open and allow signing to Microsoft but it pops up for a split second and closes. if anyone had that problem or got a fix for me it would be much appreciated. thanks!
If anyone still has this problem, I just want to share my solution and my problem which is similar to this.
TL;DR
Your SHA-1 Fingerprint may be used by another Firebase project so either delete that fingerprint or sign with a different keystore
Long Version
I worked on a project that has a development and production environment using different Firebase projects. We use Firebase Auth to link Microsoft login for our Android app. I got the same error as above while trying to set up the development environment of the project. We used to only have one environment for Firebase so this was never a problem.
It turns out that when you don't provide an SHA-1 fingerprint when you create the project, Firebase automatically adds them when you run an authentication call. This meant that when we created debug APKs for testing, the SHA-1 fingerprint was recorded to the Firebase project that was intended for the live environment so when you try to add the same fingerprint in another project it won't let you. The solution would be to include the SHA-1 fingerprint in the development environment but to do so you would need to delete it the fingerprint from the live environment (in my case) and wait for that change to reflect. Or you could sign with a different, unused keystore.
You need to have microsoft (hotmail, outlook ...) account on your android, to solve this problem.
If user turn off both wi-fi, 3g, 4g, and so on and reverse (no internet connection). Firebase database name child connections:(true/false)
So, when internet connections, wi-fi, 3g, 4g, and so on are off or missing, the user is offline so he can't be found.
Remember the two scenarios: Before and After. If user is offline before an other user search him, then he will not displayed in the list result, if user is off-line after an other user search him, then it will display NO MORE AVAILABLE icon on the user
Kindly some one help me for this problem.
To solve this, you can create a new node in your Firebase Realtime Database to hold all online users, so when the user opens the application, you'll immediately add his id to this newly created node. Then, if you want to check if the user is online, just check if his id exists in the list.
You can also add a new property named isOnline for each user in your database and then update it accordingly.
For that, I recommend you using Firebase's built-in onDisconnect() method. It enables you to predefine an operation that will happen as soon as the client becomes disconnected.
See Firebase documentation.
You can also detect the connection state of the user. For many presence-related features, it is useful for your app to know when it is online or offline. Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example also from the official documentation:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
Though this is more than a year late, to clear up the confusion. Alex's question would like to implement a live chat scenario in which each user can view everyone's online status at their ends or on their devices.
A simple solution be to create a node where all users would inject their online status each. e.g.
//say your realtime database has the child `online_statuses`
DatabaseReference online_status_all_users = FirebaseDatabase.getInstance().getReference().child("online_statuses");
//on each user's device when connected they should indicate e.g. `linker` should tell everyone he's snooping around
online_status_all_users.child("#linker").setValue("online");
//also when he's not doing any snooping or if snooping goes bad he should also tell
online_status_all_users.child("#linker").onDisconnect().setValue("offline")
So if another user, say mario checks for linker from his end he can be sure some snooping around is still ongoing if linker is online i.e.
DatabaseReference online_status_all_users = FirebaseDatabase.getInstance().getReference().child("online_statuses");
online_status_all_users.child("#linker").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String snooping_status = dataSnapshot.getValue(String.class);
//mario should decide what to do with linker's snooping status here e.g.
if(snooping_status.contentEquals("online")){
//tell linker to stop doing sh*t
}else{
//tell linker to do a lot of sh****t
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I'm very new to Android and since I'm a self learner I've been stuck with the following problem.
I have a simple code in MainActivity as
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String sapCode = String.valueOf(sapcode.getText());
String userName = String.valueOf(username.getText());
String pwd = String.valueOf(password.getText());
if (sapCode.equals("017343") && userName.equals("root") &&
pwd.equals("root123")) {
message.setText("Login Successful!");
System.out.println("After successful and before Intent");
Intent intent = new Intent(context, HomeActivity.class);
startActivity(intent);
} else {
message.setText("Login Unsuccessful!");
}
}
});
As you can see in the above code by taking user credentials from view, I'm authenticating by giving hard coded values.
But Instead to that code, Indeed I should make rest call to my webapplication for login by providing these credentials in a post method. The URL looks like
http://myapp.co.in/login.do (or) http://myapp.co.in/rest/login
So that my java code inside my webapplication can access these values and authenticate based on those values.
Now My Questions are
1) How to make such request from my android app?
2) If authentication succeeded in my Web Application then how can I manage the session in my android app?
There are the problems I've been come across and I've been stuck with it. Any help will be appreciated. Thank you.
1. To make a client web-service call, use HttpURLConnection. The official tutorial is here;
2. To persist a session in Android, you can either make use of CookieStore or manually save, clear and retrieve the user_id or session_id in a SharedPreference.
There you go.
EDIT:
HttpClient should be used on Froyo & Eclair, while HttpURLConnection is preferred for Gingerbread and up. For the differences between the various connection approaches, see Android's HTTP Clients.