Firebase Anonymous Authentication same reference object issue - java

I want to delete the Anonymous account in my Firebase Authentication database when login with the non-anonymous accounts (Google Login, Facebook login, etc).
In my code below, when user opens app Anonymous account creating successfully and I set the anonymous FirebaseUser object to firebaseUserAnonymous.
But when I log in with Google account uidOld and uidNew ids is the same every time!
So I debug my code and see onAuthStateChanged method's FirebaseUser object and before set firebaseUserAnonymous object is the same!
if (firebaseUserAnonymous != null && !uidNew.equals(uidOld)) is never calling, because the new firebaseUser object and the old firebaseUserAnonymous object always same reference?
So onAuthStateChanged method is always using the same object when new anonymous login or google login.
How can I delete the old FirebaseUser anonymous object when the user login with google log in?
private FirebaseUser firebaseUserAnonymous;
FirebaseAuth.getInstance().addAuthStateListener(new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
if (firebaseUser == null) {//When first open or logout
FirebaseAuth.getInstance().signInAnonymously();
} else {
String uidOld = firebaseUserAnonymous != null ? firebaseUserAnonymous.getUid() : null;
String uidNew = firebaseUser.getUid();
if (firebaseUserAnonymous != null && !uidNew.equals(uidOld)) {//Must be call when user login after google login for delete old anonymous account, but never calling
firebaseUserAnonymous.delete();
}
if (firebaseUser.isAnonymous()) {
firebaseUserAnonymous = firebaseUser;
}
}
}
});

Related

Error "is not an enclosing class" while Implement Firebase Auth in a Login Activity Android Java

I have an android app that I created using the Login Activity Template (New Project -> Login Activity -> Java, API 26), which created a scaffold with the data and ui.login packages. I'm trying to implement Firebase auth with email & password.
Following the docs and also understanding the function of each class, I started touching the class LoginDataSource (from data package) and adding the following code:
public class LoginDataSource {
private static final String TAG = "EmailPassword";
private FirebaseAuth mAuth;
public Result<LoggedInUser> login(String username, String password) {
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
try {
mAuth.signInWithEmailAndPassword(username, password)
.addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithEmail:success");
//FirebaseUser user = mAuth.getCurrentUser();
//updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.getException());
//Toast.makeText(LoginActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
//updateUI(null);
}
}
});
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
Log.d(TAG,"user display name: " + user.getDisplayName());
LoggedInUser appUser = new LoggedInUser( user.getUid(), user.getDisplayName());
return new Result.Success<>(appUser);
} catch (Exception e) {
return new Result.Error(new IOException("Error logging in", e));
}
As I understand, the addOnCompleteListener expects my activity, which lives in the ui.login package, so when I try to use it, I get the error:
'com.example.appname.ui.login.LoginActivity' is not an enclosing class
When I use the this keyword, I get the error:
Cannot resolve method 'addOnCompleteListener(com.samuelkb.aipuzzles.data.LoginDataSource, anonymous com.google.android.gms.tasks.OnCompleteListener<com.google.firebase.auth.AuthResult>)'
It makes sense to keep the logic in my data package and not in my UI package.
I'm unsure how I should implement Firebase in my app, so any guidance is welcome.

documentRef.get() not executed, simply ignored and passed over

My app should retrieve for the user the single String field "itemList" of their FireStore db document (named after their userID) to a String variable "json"
structure of FireStore db
if (currentUser != null) {
Log.d(TAG, "userID = " + currentUser.getUid());
documentRef.get()
.addOnSuccessListener(documentSnapshot -> {
Log.d(TAG, "success");
json = documentSnapshot.getString("itemList");
})
.addOnFailureListener(e -> {
Log.d(TAG, "failure");
});
}
The first log prints the proper userID, so the connection and authentication with Firebase are made.
But documentRef.get() is never executed (none of its two logs is printed). "json" remains indeed null, though an inspection through Firebase Console shows "itemList" contains the String data it is supposed to.
documentRef is initiated as
FirebaseFirestore db;
DocumentReference documentRef;
db = FirebaseFirestore.getInstance();
documentRef = db.collection("Users").document(currentUser.getUid());
which is preceded by the authentication section:
FirebaseAuth auth;
FirebaseUser currentUser;
auth = FirebaseAuth.getInstance();
currentUser = auth.getCurrentUser();
And these are the FireStore security rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{userID} {
allow create, read, write, delete : if request.auth.uid == userID;
}
}
}
So it looks like documentRef.get() is being entirely ignored. There are no error messages. Of course, futher down the road, when it starts to use "json", the app throws a nullPointerException, because "json" has remained null.
I tried on both a virtual device in Android Studio and a real phone.
What is wrong?
PS: writing String data to "itemList" with documentRef.set() was no problem, as confirmed through Firebase Console. It is actually this data the app is trying to retrieve.

After creating a user with email and password with Android Firebase I cannot save additional information in a users collection

After creating a user using the firebaseAuth function createUserWithEmailAndPassword (email, password) I am trying to save additional information of the users that are registered in a collection called "users". For that I use DocumentReference:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
FirebaseUser fuser = FirebaseAuth.getInstance().getCurrentUser();
String idUser = fuser.getUid();
DocumentReference documentReference = fStore.collection("users").document(fuser.getUid());
Map<String, Object> user = new HashMap<>();
Log.d("data", "username: "+username + " telef: "+telefono);
user.put("username", username);
user.put("telefono", telefono);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "User profile created");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "can´t create profile: "+e.toString());
}
});
//sign out the user.. dont work.. any ideas?
FirebaseAuth.getInstance().signOut();
mProgressBar.dismiss();
//send the user to log in
Intent intent = new Intent(RegisterActivity.this, loginActivity.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
RegisterActivity.this.finish();
Toast.makeText(getApplicationContext(), "Registered ok!", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "can´t register", Toast.LENGTH_LONG).show();
}
}
});
Apart from having instantiated:
mAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
I have also been forced to add the following:
private void initFirebase() {
FirebaseApp.initializeApp(this);
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase.setPersistenceEnabled(true);
databaseReference = firebaseDatabase.getReference();
}
Not even with the latter it works. Only the user with email and password is registered. The strange thing is that there is no error, it seems that the onSuccess or onFailure event does not occur. The database rules in the firebase console are:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
Basically this rule indicates that the user must be authenticated to be able to read / write to the database. My dependencies are:
implementation 'com.google.firebase:firebase-auth:19.3.0'
implementation 'com.google.firebase:firebase-firestore:21.4.2'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:18.0.1'
I should use firebase-firestore and firebase-auth but I have added firebase-database and firebase-storage in order to solve the problem but nothing happens.
Thanks in advance.
Your code is signing out the user before the database is written, so the write will fail any database rules that require the user to be signed in.
documentReference.set(user) is asynchronous and returns immediately, before any work has been done. The database will be written some time later. Meanwhile, your code goes on to immediately execute a signout with FirebaseAuth.getInstance().signOut(), which deletes the user's auth token, making the query happen without any credentials.
If you need the user to be signed out after writing the database, you should do that inside the database callback code. Though it's entirely clear to me why you would want that to happen. You should probably just remove the signout completely.

How to retrieve the real name (Name and surname) of a Facebook profile that signed in with Firebase?

How can I retrieve the real first name and surname of a Facebook profile that logged in using the Firebase authentication?
mAuth = FirebaseAuth.getInstance();
fullNameTextView.setText(mAuth.getCurrentUser().getDisplayName());
userNameTextView.setText(mAuth.getCurrentUser().getDisplayName());
Picasso.get().load(mAuth.getCurrentUser().getPhotoUrl()).placeholder(R.drawable.ic_action_profile).into(profilePictureImageView);
That information doesn't exist in the FirebaseUser object. To solve this, you should first get the list of providers and find the one you are interested in. So please check the following lines of code:
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
List<? extends UserInfo> userInfoList = firebaseUser.getProviderData();
for (UserInfo userInfo : userInfoList) {
String providerId = userInfo.getProviderId();
if (providerId.equals(FacebookAuthProvider.PROVIDER_ID)) {
String name = userInfo.getDisplayName();
Log.d("TAG", name);
}
}
The result in the logcat will be the name of the user that has was authenticated using Facebook.

Firebase realtime database doesn't update database when i sign up

I am trying to send information to the firebase database, I am connected and already checked multiple times and i can't find the error here's my code
Here's the database reference command
everything is well put together and working, i don't exactly know why it doesn't really allow me to send information doesn't show any errors and everything
userInformation = FirebaseDatabase.getInstance().getReference("Users").child("Users");
firebaseAuth = FirebaseAuth.getInstance();
private void saveUserInformation(){
String UserName = NameET.getText().toString();
String Userbirthday = dateBirth.toString();
String Userdate_drivinglicense = dateLicense.toString();
String UserCountry = Countries.getSelectedItem().toString();
String UserGender = Genders.getSelectedItem().toString();
String HouseLocationLat = String.valueOf(location.getLatitude());
String HouseLocationLong = String.valueOf(location.getLongitude());
Userinformation userInfo = new Userinformation(UserName,Userbirthday,Userdate_drivinglicense,UserCountry,UserGender,HouseLocationLat,HouseLocationLong);
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
userInformation.child(user.getUid()).setValue(userInfo);
}
Toast.makeText(UserInformationActivity.this, "Saving Information", Toast.LENGTH_SHORT).show();
}
The Issue i had was that i didn't implent an Getter and Setter in my Java Class which is connected to the UserInformation, and i had to create a new child in the database with the name "Users" since it wasn't created automatically as it should be, also changed the names of variables in my
Userinformation userInfo = new Userinformation(UserName,Userbirthday,Userdate_drivinglicense,UserCountry,UserGender,HouseLocationLat,HouseLocationLong);
So it can connect to the database correctly Thanks for all the help :)

Categories