Im using Facebook Authentication with Firebase and I'm trying to get the Photo Url from the authenticated user. I've tried using the following method:
String photoUrl = firebaseUser.getPhotoUrl().toString();
And this method :
String photoUrl = firebaseUser.getProviderData().get(0).getPhotoUrl().toString();
They both return a url in the format : https://scontent.xx.fbcdn.net/v/t1.0-1/p100x100/1230538156_10205381561684678_351630538156623_n.jpg
When I try to access this url, I get the following message:
"Access to scontent.xx.fbcdn.net was denied"
As an alternative, I have tried getting the user's facebook id so I can request the photo using the Graph API but seems to be no way to get the facebook id. I thought the following would work:
firebaseUser.getProviderData().get(0).getProviderId();
But this returns the string "firebase" ??? ...umm what?
My full method:
private void firebaseAuthWithFacebook(AccessToken token) {
showProgressDialog("Signing in with Facebook","Signing in with Facebook");
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
if(task.isSuccessful()){
FirebaseUser user = mAuth.getInstance().getCurrentUser();
if (user != null) {
addNewUserFacebook(user);
}
}
else{
Toast.makeText(SignInActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
}
hideProgressDialog();
}
});
}
private void addNewUserFacebook(FirebaseUser firebaseUser){
String name = firebaseUser.getDisplayName();
String email = firebaseUser.getEmail();
/*My THREE failed methods - cue sad trombone */
//String photoUrl = firebaseUser.getPhotoUrl().toString();
//String photoUrl = firebaseUser.getProviderData().get(0).getPhotoUrl().toString();
String photoUrl = "https://graph.facebook.com/" + firebaseUser.getProviderData().get(0).getProviderId() + "/picture?type=large";
String providerId = "Facebook";
final String uid = firebaseUser.getUid();
User user = new User(name, email, photoUrl, providerId);
rootRef.child("users").child(uid).setValue(user, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError == null){
//add local user information
updateUser(uid);
}
}
});
}
Well, I had the same problem, I deleted all the data from the Facebook application in the configuration on the phone, no data, I tried and the problem solved, Facebook gets dizzy I think.
this method works for me
String photoUrl = firebaseUser.getProviderData().get(0).getPhotoUrl().toString();
Related
I am trying to register 20 users and create a document on my collection for each of them on Firebase Firestore. My program successfully registers 20 users but fails when creating documents for them. 18, 19 documents created each time but it almost always skip to create a document for the first member and the last member of my array. StudentCreator is just a file that has a parent array, student array with 20 items.
Here is an array from studentCreator.java
public static String parent_names[]={
"Ahmet Lola",
"Hüseyin Kutlutürk",
"Ümit Uğrak",
"Veysel Karani",
"Serkan Gotar",
"Dündar Zalim",
"Kadir Berkay",
"Uğur Özdemir",
"Bünyamin Akgün",
"Kaptan Price",
"Selim Tekiner",
"Gökçe Yılan",
"Talip Özkan",
"Abdurrahman Tarikçi",
"Selim Kirlier",
"Hasan Can Doğan",
"Erdem Gökşen",
"Fatoş Ünal",
"Nurgül Birtek",
"Yuan Hui"};
Here the main code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Intent LoginActivity = new Intent(this,LoginActivity.class);
final Intent TeacherActivity = new Intent(this,TeacherActivity.class);
final Intent ParentActivity = new Intent(this,ParentActivity.class);
final Intent ManagerActivity = new Intent(this,ManagerActivity.class);
for (int i = 0; i < 20; i++)
{
mAuth = FirebaseAuth.getInstance();
final String username = StudentCreator.parent_names[i].replaceAll(" ", "") + StudentCreator.student_numbers[i];
final String email = username + "#onurmail.com";
final String password = "123456";
final String student_name = StudentCreator.student_names[i];
final String parent_name = StudentCreator.parent_names[i];
//Registration is successul here.
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(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("User Registered", "createUserWithEmail:success");
final FirebaseUser user = mAuth.getCurrentUser();
final String user_id = user.getUid();
//I get valid userId's for 20 users.
//CREATE STUDENT OBJECT AND FIREBASE INSTANCES
final FirebaseFirestore db = FirebaseFirestore.getInstance();
final Map<String, Object> student = new HashMap<>();
student.put("student_name", student_name);
student.put("parent_name", parent_name);
//My first element of array comes here and prints its parent name and student name perfectly but cant see anything about it on database.
//PUT STUDENT TO THE DB
db.collection("TED_Ankara")
.document(parent_name)
.set(student)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "User inserted sucessfully: "+parent_name,
Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(), "User cannot be inserted: "+parent_name,
Toast.LENGTH_SHORT).show();
}
}
});
//PUT STUDENT TO THE DB
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(getApplicationContext(), "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
Please help. I am suspicious about addOnCompleteListener and firebaseAuth's usage. But i am not sure really. Thanks for any help.
Edit: Adding the first member without the for loop works without any problem. So i guess the problem is about the for loop.
The Firebase SDK only can have a single active user. Since you're running over the array in a so-called tight loop, I suspect that you may be creating a next user, before the code has started writing the document for the previous user. To verify whether this is indeed the problem, can you try to see if this fixes it?
Add a function to create the users
void createNextUser(List<String> student_names, List<String> student_numbers, List<String> parent_names) {
if (student_names.size() > 0 && student_numbers.size() > 0 && parent_names.size() > 0) {
final String student_name = student_names.remove(0);
final String student_number = student_numbers.remove(0);
final String parent_name = parent_names.remove(0);
final String username = parent_name.replaceAll(" ", "") + student_number;
final String email = username + "#onurmail.com";
final String password = "123456";
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(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("User Registered", "createUserWithEmail:success");
final FirebaseUser user = mAuth.getCurrentUser();
final String user_id = user.getUid();
//I get valid userId's for 20 users.
//CREATE STUDENT OBJECT AND FIREBASE INSTANCES
final FirebaseFirestore db = FirebaseFirestore.getInstance();
final Map<String, Object> student = new HashMap<>();
student.put("student_name", student_name);
student.put("parent_name", parent_name);
//My first element of array comes here and prints its parent name and student name perfectly but cant see anything about it on database.
//PUT STUDENT TO THE DB
db.collection("TED_Ankara")
.document(parent_name)
.set(student)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "User inserted sucessfully: "+parent_name,
Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(), "User cannot be inserted: "+parent_name,
Toast.LENGTH_SHORT).show();
}
// Now that we're done with this user, move on to the next one
createNextUser(student_names, student_number, parent_names);
}
});
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(getApplicationContext(), "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
}
The big difference in this code is that it only starts creating the next user, once it's done creating the previous user and its document. It does this by:
removing the current student from the list when it starts
final String student_name = student_names.remove(0);
final String student_number = student_numbers.remove(0);
final String parent_name = parent_names.remove(0);
calling itself after writing the document
// Now that we're done with this user, move on to the next one
createNextUser(student_names, student_number, parent_names);
Now all that is left to do is kicking off the process in your onCreate with:
createNextUser(Arrays.asList(StudentCreator.student_names), Arrays.asList(StudentCreator.student_numbers), Arrays.asList(StudentCreator.parent_names));
Note: creating accounts for other users is an administrative action, and as such should typically not be performed from an Android client. I highly recommend checking out the Firebase Admin SDK, which has better support for such operations. It must be used in a trusted environment, so not in an Android app, such as your development machine, a server you control, or Cloud Functions.
Everything worked but not showing name only.
My code is:
user = profAuth.getCurrentUser();
if (user != null) {
// Name, email address
String uid = user.getUid();
String name = user.getDisplayName();
String email = user.getEmail();
txtName.setText(name);
txtEmail.setText(email);
txtUserid.setText(uid);
}
That's because Firebase Auth doesn't prompt the user to provide a Display name when signing up with Email/Password. But you can do that manually. Prompt the user to type the display name he desires, and pass it to the setDisplayName() method bellow:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(desiredName)
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User display name updated.");
}
}
});
I have been working with my app and I have set up the authentication method using email and password. I also need to set up a display name for the user which will be used in other activities such as "profile".
I have been using following method, however it does not setting the display name as I don't see it to appear in log cat. Would somebody be able to tell me where I am making mistake or should I use some other method for setting the display name.
Thanks
private void registration(){
final String email = Email.getText().toString().toString().trim();
final String password = Password.getText().toString().trim();
final String username = Username.getText().toString().trim();
final String age = Age.getText().toString().trim();
final String userID = userAuth.getCurrentUser().getUid();
if (!TextUtils.isEmpty(email)&& !TextUtils.isEmpty(password)&& !TextUtils.isEmpty(username)&& !TextUtils.isEmpty(age)){
showProgress.setMessage("Registration in progress...");
showProgress.show();
userAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
String user_id = userAuth.getCurrentUser().getUid();
DatabaseReference current_user_db = DatbaseOfUsers.child(user_id);
current_user_db.child("email").setValue(email);
current_user_db.child("username").setValue(username);
current_user_db.child("Age").setValue(age);
current_user_db.child("uID").setValue(userID);
showProgress.dismiss();
AuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if(user != null){
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(username).build();
user.updateProfile(profileUpdates);
Log.v(TAG, username);
}
}
};
//After user is created main screen intent is called
Intent mainpage = new Intent(RegisterActivity.this, MainPageActivity.class);
mainpage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mainpage);
}
else if(!task.isSuccessful()){
showProgress.dismiss();
Toast.makeText(RegisterActivity.this,"Error While Register",Toast.LENGTH_LONG).show();
}
}
});
}
Take the username along with the intent
Do this way...
mainpage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent .putExtra("the key you wish to give ex:name ",username);
Then in mainpage retrieve the username by this way
String u_name;
In On create
u_name=Objects.requireNonNull(getIntent().getExtras()).getString("name");
Now u can use that username anywhere by accessing u_name
I'm trying to create an profile activity, where users can change those Profile picture and Display name, I'm trying to update user photo or user name, CompleteListener called, task.isSuccessful = true but nathing done, why?
Function to update name:
FirebaseUser mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final String newName;
newName = input.getText().toString();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(newName)
.build();
mFirebaseUser.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
DatabaseReference mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference().child("users");
mFirebaseDatabaseReference.child(mFirebaseUser.getUid()).child("DisplayName").setValue(newName);
updateUI();
Toast.makeText(ProfileActivity.this, "User display name updated.", Toast.LENGTH_SHORT).show();
} else
Toast.makeText(ProfileActivity.this, "Error while updating display name.", Toast.LENGTH_SHORT).show();
}
});
Same when i'm trying to update Profile picture that I just uploaded to Firebase Storage...
And idea?
EDIT:
Sometimes the username really get updated, I think it's take like more then 10 minutes to update, why?
I have had a similar problem where the User information was not updating until the User re-authenticated. I resolved it by also saving this information in my firebase database. For me this made sense, as I wanted Users to be able to get basic information about other Users anyway.
My code ended up looking something like this. When the account is created, or modified, I made a call to the "users/{uid}" endpoint and updated the object there. From here I used the GreenRobot EventBus to send my new User object to whoever was subscribed so that it would be updated on the screen.
private FirebaseUser firebaseUser;
public void createUser(String email, String password, final User user, Activity activity, final View view) {
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(activity, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());
// If sign in fails, display a messsage to the user. If sign in successful
// the auth state listener will be notified and logic to handle
// signed in user can be handled in the listener
if (!task.isSuccessful()) {
Snackbar.make(view, task.getException().getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
} else {
firebaseUser = task.getResult().getUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(user.displayName)
.build();
firebaseUser.updateProfile(profileUpdates);
updateDatabase(user);
EventBus.getDefault().post(new LoginEvent());
}
}
});
}
public boolean updateDatabase(User user) {
if (firebaseUser == null) {
Log.e(TAG, "updateDatabase:no currentUser");
return false;
}
return userReference.setValue(user).isSuccessful();
}
The setup of the database watcher was done something like this. Note that you need to make sure that you remove the listener when the User logs out and add a new one when the User logs in.
protected void setupDatabaseWatcher() {
String uid = firebaseUser.getUid();
userReference = FirebaseDatabase.getInstance().getReference("users/" + uid);
userReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
User user = dataSnapshot.getValue(User.class);
Log.d(TAG, "Value is: " + user);
EventBus.getDefault().post(new UserUpdateEvent(user));
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
}
Use this simple code:
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(newName)
.build();
I'm new android learner so its is difficult for me to do stuffs which I cannot find in the documentation. Here is my code for creating users
mAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
//Successfully Registered
Toast.makeText(RegisterActivity.this, "Registration Successful", Toast.LENGTH_SHORT).show();
}else {
//Error occurred during registration
Toast.makeText(RegisterActivity.this, "Registration Unsuccessful", Toast.LENGTH_SHORT).show();
try {
throw task.getException();
} catch(FirebaseAuthWeakPasswordException e) {
editTextPassword.setError(e.getMessage());
editTextPassword.requestFocus();
}catch(FirebaseAuthUserCollisionException | FirebaseAuthInvalidCredentialsException e) {
editTextEmail.setError(e.getMessage());
editTextEmail.requestFocus();
} catch(Exception e) {
Log.e(RegisterActivity.class.getName(), e.getMessage());
}
}
progressDialog.dismiss();
}
});
This only takes two parameters(email and password) to create an user. To create user with more fields what approach should I take.
I have also added a FirebaseAuth.AuthStateListener() to check user login status. But when I'm calling firebaseAuth.getCurrentUser().getDisplayName() after successfully user login it returns null as usual.So how can I create user with Names so I can retrieve it with firebaseAuth.getCurrentUser().getDisplayName().
After the registration is successful,
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName("Jane Q. User")
.build();
EDIT: This code is a bit incomplete as profileUpdates is never accessed.
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User profile updated.");
}
}
});
Then, to retrieve it, use this wherever required,
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// Name, email address etc
String name = user.getDisplayName();
String email = user.getEmail();
}
To add a user with extra information such as User's name or other required information you should store these data using the Firebase real-time database under the unique user_id generated upon successful completion of email and password registration.
Get user input for name in registration form,
String name = mNameField.getText().toString().trim();
Add user's name in onComplete method :
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
String user_id = mAuth.getCurrentUser().getUid;
DatabaseReference current_user = mDatabase.child(user_id);
current_user.child("name").setValue(name);
progressDialog.dismiss();
}