FirebaseUser password not updating through updatePassword() method in android - java

I am trying to update or reset the user's password in my Android application using Firebase Authentication. For this, I am using the updatePassword() method provided by FirebaseUser class, but it is throwing the code in addOnFailureListener() and I am unable to figure out why. please help me. I have provided the code to update the password below:
updatePasswordButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String newPassword = enterPasswordEditText.getText().toString().trim();
String confirmPassword = confirmPasswordEditText.getText().toString().trim();
if (!newPassword.equals(confirmPassword)) {
Toast.makeText(EditProfileActivity.this, "Passwords don't match!", Toast.LENGTH_SHORT)
.show();
} else {
//Updating password
firebaseUser.updatePassword(newPassword)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(EditProfileActivity.this, "Password changed successfully", Toast.LENGTH_SHORT)
.show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(EditProfileActivity.this, "Error in changing password", Toast.LENGTH_SHORT)
.show();
}
});
}
}
});

You're getting the following error:
Error in changing password: This operation is sensitive and requires recent authentication. Log in again before retrying this request
Because changing the password is considered a sensitive operation. This means that in order to perform that operation, Firebase requires that the user has recently signed in.
If the user hasn't recently signed in, meaning that 5 minutes have already passed, when you try to perform such a sensitive operation, Firebase throws an exception that contains the error message from above.
The simplest solution for this situation would be to ask the user to re-enter their credentials and retry the operation.
Here is the official documentation for FirebaseAuthRecentLoginRequiredException.

Related

GitHub Authentication for Android Through Firebase

Hello I want to know how can I access user email while authenticating a user through Github in my android App. I am using firebase and android studio. Please note that I cannot use user.getEmail in onSuccesslistner because I am also using Google authentication, which throws exception that email already exist and pending task method works for first time only. Basically I want to use setScopes to retrieve the user Email. I have to get Email and check if user exist in my database in simply logged in user.
Here is my Code:
public void git_login(View view)
{
SignInWithGithubProvider(
OAuthProvider.newBuilder("github.com")
.setScopes(
new ArrayList<String>()
{
{
add("user:email");
}
}).build()
);
}
private void SignInWithGithubProvider(OAuthProvider login)
{
Task<AuthResult> pendingResultTask= mAuth.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) {
Toast.makeText(getApplicationContext(), "User Exist" + authResult, Toast.LENGTH_SHORT).show();
// 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) {
// Handle failure.
}
});
}
else {
// There's no pending result so you need to start the sign-in flow.
// See below.
mAuth.startActivityForSignInWithProvider(this , login).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e)
{
if (e.toString().equals("com.google.firebase.auth.FirebaseAuthUserCollisionException: An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address."))
{
showDialogAlert();
}
}
}).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
FirebaseUser user = mAuth.getCurrentUser();
Toast.makeText(getApplicationContext(), "Login" + user.getUid() +"\n"+user.getEmail(), Toast.LENGTH_SHORT).show();
userNameForDb = user.getDisplayName();
userImageForDb = String.valueOf(user.getPhotoUrl());
userEmailForDb = user.getEmail();
Toast.makeText(CreateNewAccountActivity.this, "Account added to Firebase: " +userNameForDb+"\n"+userEmailForDb+"\n"+userTokenForDb, Toast.LENGTH_SHORT).show();
saveDataToDb(userNameForDb , userEmailForDb , userTokenForDb);
}
});
}
}
```
I want to know how can I access user email while authenticating a user through Github
The simplest solution I can think of is once you are successfully authenticated, you can get the email address from the "userInfo" object like in the following lines of code:
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
for (UserInfo userInfo : firebaseUser.getProviderData()) {
if (userInfo.getProviderId().equals("github.com")) {
Log.d(TAG, "User is signed in with Github");
Log.d(TAG, "email: " + userInfo.getEmail());
}
}
}
The output in the logcat will be the email address that was used by the user for the authentication process.
Edit:
It's true, if the user is already registered with a Gmail account, you'll get an Exception that says that such an account is already there. So you need to use for authentication Google credentials.
I actually want to get the user id in this case and want to check it in my database which is my local server that this email exists or not.
There is no need for that because you can handle the Exception, and indicate to the user that a Google account is already there, and then simply use Google credentials for authentication. If there is no Exception, is obvious that the user doesn't exist yet.

Fireabase Realtime Database client requests have expired, I have re enabled them, but still entries are not created in the db?

I am working on an android app for my degree and I am using Firebase Realtime Database, the app is going to be something similar to spotify, but on a smaller scale. I was forced to take a longer break and my client requests from the Database have been automatically disabled (the 30 day limit by default).
I've changed the rules to be "true" for both read and write(for the purpose of making it work, not secure, I will change them appropriately). I also attached some screenshots and code snippets to help. I checked other stack questions and they didnt help, the only solution I see right now is making another project so basically reinitializing the whole thing withing a new Firebase project.
private void registerUser(){
final String email = emailField.getText().toString().trim();
final String username = usernameField.getText().toString().trim();
String password = passwordField.getText().toString().trim();
String confirmPass = confirmPasswordField.getText().toString().trim();
if(username.isEmpty()){
usernameField.setError("Username is required");
usernameField.requestFocus();
return;
}
if(email.isEmpty()){
emailField.setError("Email is required");
emailField.requestFocus();
return;
}
if(password.isEmpty()){
passwordField.setError("Password is required");
passwordField.requestFocus();
return;
}
if(!Patterns.EMAIL_ADDRESS.matcher(email).matches()){
emailField.setError("Please provide valid email");
emailField.requestFocus();
return;
}
if(password.length() < 6){
passwordField.setError("Password length should be at least 6 characters");
passwordField.requestFocus();
return;
}
if(!password.equals(confirmPass)){
confirmPasswordField.setError("Passwords do not match");
confirmPasswordField.requestFocus();
return;
}
progressBar.setVisibility(View.VISIBLE);
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
User user = new User(username, email);
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(RegisterActivity.this, "User has registered successfully", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(RegisterActivity.this, "Registration has failed", Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(View.GONE);
}
});
}
}
});
}
This is where I register my user to the Realtime Database. They do show up in the authentication tab and I can log in with them, but they do not in the database.
{
"rules": {
"users": {
".read": "true",
".write": "true",
}
}
}
These are the rules that I am using right now with the purpose of getting to the bottom of this issue that I am having right now, I am planning to change them so that the users can only write data that belongs to them.
Basically my question boild down to, if my client requests have expired, what can I do to re enable them so that I can have entries in my Realtime DB again? This is the DB right now

Android firebase throws authentication error while trying to access storage

EDIT: I just restarted Android Studio after cleaning the project and invalidating cache. Now I get this error -
E/StorageException: { "error": { "code": 403, "message":
"Permission denied. Could not perform this operation" }}
I'm getting the following error that prints infinitely.
2020-09-27 17:00:32.931 11755-11863/com.example.XXXXXX E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.internal.api.FirebaseNoSignedInUserException: Please sign in before trying to get a token.
In my app I've created the user properly, and FirebaseAuth.getInstance().getCurrentUser(); does NOT return null. But if it does, I handle it by logging them in successfully or creating another user. My app now has 160+ users created, in less than half a day. I don't think I've even run the app that many times for testing. 'Sign in with email', and 'anonymous sign in' options are enabled in auth settings.
The problem starts when I try to access the storage. I get the above mentioned auth token error. The folder and file exist and this is how I'm trying to download the files -
fstore.child("gs://XXXXXX-XXXX.appspot.com/Books/XXXX").listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult listResult) {
for(StorageReference sref : listResult.getItems())
{
tempFilename = sref.getName();
File tmpFile = new File(tempSubDir, tempFilename);
try {
tmpFile.createNewFile();
sref.getFile(tmpFile).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(tabtwoactivity.this, "File download failed!", Toast.LENGTH_LONG).show();
System.out.println("ERROR: "+ e.toString());
}
});
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println("IIIIII: "+sref.getName());
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(tabtwoactivity.this, "Fetching Directory XXXXX Failed", Toast.LENGTH_LONG).show();
}
});
I've tried using fstore.child("XXXX").listAll() but that gave me an avalanche of different errors, mainly focused around Folder not found. My storage has the folder and files. I've even played around with the storage rules - allow read, write;, allow read, write: if request.auth!=null, allow read, write: if request.auth==null. But nothing worked.
What am I doing wrong?
Paste this in your google.json:
service firebase.storage {
// The {bucket} wildcard indicates we match files in all storage buckets
match /b/{bucket}/o {
// Match filename
match /filename {
allow read: if true;
allow write: if true;
}
}
}

Is there a way to use Google Sign In without adding the account to the device?

I'm making an app that needs the user to authenticate with Google, but it has to be done using email/password and the logged in account must not be added to the device account list.
Login is an easy thing to do with Google SignIn but it doesn't meet my requirements.
I've searched similar questions but it seems there was no solution at the time,
here and
here
Maybe now with the new versions of GoogleSignInClient or something similar is there a way to achieve this?
I just need to check email and password are correct.Thanks in advance.
you can create an account without adding the account in your device you have to create 2 edit text and just enter that email-id and password on these fileds and pass in a method just like that:-
FirebaseAuth mAuth = FirebaseAuth.getInstance();
createAccount(registerEmail.getText().toString(), registerPassword.getText().toString());
and create a method:-
private void createAccount(String email, String password) {
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
pd.dismiss();
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "You are registered successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, task.getException().getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
}

Google Play Games API returns SIGN_IN_REQUIRED

I'm trying to implement automating player sign in to Google Play games in my Android app. Firstly, as mentioned here, I try to sign in silently:
#Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this, task -> {
if (task.isSuccessful())
//everything ok
else {
final ApiException exception = (ApiException) task.getException();
if (BuildConfig.DEBUG)
Log.d(TAG, "Silent Sign In failure: ", exception);
if (exception.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED)
startSignInIntent();
}
});
Every time I got an exception with code 4 (CommonStatusCodes.SIGN_IN_REQUIRED). So in this case I try to sign in with ui:
private void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
#Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == RC_SIGN_IN) {
final GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// everything is ok, get account from result
} else if (result.getStatus().hasResolution()) {
resolveManually(result.getStatus());
} else {
String message = result.getStatus().getStatusMessage();
if (BuildConfig.DEBUG)
Log.d(TAG, "status code" + result.getStatus().getStatusCode());
if (message == null || message.isEmpty()) {
message = "other error";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
And here everytime I get message with other error! The status code is again 4 (CommonStatusCodes.SIGN_IN_REQUIRED). How can I get this code when I try to sign in using intent? So, my app are in infinite loop because onResume is called everytime my activity loads after receiving a result, and everytime the status code is CommonStatusCodes.SIGN_IN_REQUIRED. So, where is the problem?
In Google samples there is no information how can I handle automatic sign in, only manual with sign in buttons. But google recommends to use automating sign in. Please help anybody to understand what is wrong here.
You must not start the login screen from your onResume method. It is a silent login which works if the user wants it (by tapping a button). That's why the examples show it only this way.
There was wrong OAuth 2.0 client ID for the debug version of my app! Don't know why there is SIGN_IN_REQUIRED status code in this situation, it is really confusing!

Categories