I'm trying to make a database of users with profile pictures(stored in storage) related to their IDs.
I'm using Firebase auth,Realtime database and Realime storage.
The code work like this : In user registration process, they choose username and picture. The database is filled with Users -> userUUid -> username and URL of picture stored.
The storage stores the picture.
If I keep such name of the table (Users) code works fine, however if I try to manipulate the tables, for example if I want to make more categories like Users -> SpecialUsers / NormalUsers -> userUUid -> ... the app just crashes.. I tried debugging but saw no errors.
Is there any way how to catch these Firebase exceptions (if there is any) or any explanation why if I change the structure of the tables, the code doesn't work ?
These is the method responsible for the registration :
(this one works)
public void signUp(String email,String password,String userName)
{
auth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(task -> {
if (task.isSuccessful())
{
dbReference.child("Users").child(auth.getUid()).child("userName").setValue(userName);
//if user choose some picture
if(imageControl)
{
UUID randomID = UUID.randomUUID(); //create random UUID for the picture
final String imageName = "images/"+randomID+".jpg";
storageReference.child(imageName).putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
StorageReference myStorageRef = firebaseStorage.getReference(imageName);
myStorageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String filePath = uri.toString();
dbReference.child("Users").child(auth.getUid()).child("image").setValue(filePath).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(RegistrationActivity.this, "Write to database is successful.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegistrationActivity.this, "Write to database is not successful.", Toast.LENGTH_SHORT).show();
}
});
}
});
}
});
}
else
{
dbReference.child("Users").child(auth.getUid()).child("image").setValue("null");
}
Intent intent = new Intent(RegistrationActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
else
{
Toast.makeText(RegistrationActivity.this, "There is a problem.", Toast.LENGTH_SHORT).show();
}
});
}
This doesn't work :
(As you can see the only thing changed is the structure of the tables from only 'Users' to 'superUsers' -> 'anotherCategory')
public void signUp(String email,String password,String userName)
{
auth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(task -> {
if (task.isSuccessful())
{
dbReference.child("superUsers").child('anotherCategory').child(auth.getUid()).child("userName").setValue(userName);
//if user choose some picture
if(imageControl)
{
UUID randomID = UUID.randomUUID(); //create random UUID for the picture
final String imageName = "images/"+randomID+".jpg";
storageReference.child(imageName).putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
StorageReference myStorageRef = firebaseStorage.getReference(imageName);
myStorageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String filePath = uri.toString();
dbReference.("superUsers").child('anotherCategory').child(auth.getUid()).child("image").setValue(filePath).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(RegistrationActivity.this, "Write to database is successful.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegistrationActivity.this, "Write to database is not successful.", Toast.LENGTH_SHORT).show();
}
});
}
});
}
});
}
else
{
dbReference.("superUsers").child('anotherCategory').child(auth.getUid()).child("image").setValue("null");
}
Intent intent = new Intent(RegistrationActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
else
{
Toast.makeText(RegistrationActivity.this, "There is a problem.", Toast.LENGTH_SHORT).show();
}
});
}
I suspect that the errors occurs somewhere after imageControl check.
In the second example of the code, the tables superUsers -> anotherCategory tables are created in the database, however the reference to the picture UUids is empty (not even null is placed)
What could be the error if nothing relevant to the process of storing pictures is changed ?
Related
I have already fix the read and right rules on realtime database of firebase still i am unable to read and write on it.
{
"rules": {
".read": "true",
".write": "true"
}
}
And i have also tried this :
{
"rules": {
".read": true,
".write": true
}
}
Firebase Storage Rule:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
Firebase Storage Rule is Working Correctly because the image gets uploaded and onSuccessListener get called.
The Code Which i am using to setValue on database is shown below and
I have already defined references as :
storageReference = FirebaseStorage.getInstance().getReference("Events_Details");
databaseReference = FirebaseDatabase.getInstance().getReference("Events_Details");
private void uploadUserInformationToDatabase() {
progressDialog.show();
if (image_uri != null) {
//this will create a big_number.jpg and when we call .child this means we are
//going to add something inside Events_Images Directory
StorageReference fileReference = storageReference.child(System.currentTimeMillis() + "." + getFileExtension(image_uri));
uploadTask = fileReference.putFile(image_uri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//Now we need to get the url of the image that you have uploaded.
Task<Uri> uri = taskSnapshot.getStorage().getDownloadUrl();
while (!uri.isComplete());
String url = uri.getResult().toString();
createUserEvent.setImageUrl(url);
//now we will save this object in our database
String uploadId = databaseReference.push().getKey();
databaseReference.child(uploadId)
.setValue(createUserEvent);
progressDialog.dismiss();
Toast.makeText(context, "Event Created Successfully", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
} else {
progressDialog.dismiss();
Toast.makeText(context, "No File Selected", Toast.LENGTH_SHORT).show();
}
}
Toast for Event Created Successfully displays every time and image also gets uploaded to storage but the object doesn't save on realtime database. And CreateUserEvent is just a class, the object of which i want to save to realtime database along with the image which i will upload to storage. The image always get success in uploading on firebase storage and after it onSuccess function gets called and inside onSuccess function i have written Code for object to save on realtime database but that doesn't work.Please help me to solve it i have already wasted 2 days of mine but can't able to fix this problem.
Ok......I have tried your code. Below is the modified function:
databaseReference = FirebaseDatabase.getInstance().getReference();
private void uploadUserInformationToDatabase() {
progressDialog.show();
if (image_uri != null) {
//this will create a big_number.jpg and when we call .child this means we are
//going to add something inside Events_Images Directory
StorageReference fileReference = storageReference.child(System.currentTimeMillis() + "." + getFileExtension(image_uri));
//now we will store our image file in firebase and check for success and failure events
//And we store the refrence of current process in this uploadtask varriable which helps us
//when user clicks on upload button multiple time, so when he clicks one time uploadTask will
//take the reference and when the upload runnig and the user clicks the upload button another
//time then we put a check if uploadTask is null or not. it is null then this means no task is
//running else we don't upload. This check you put above in upload onlicklisterner.
uploadTask = fileReference.putFile(image_uri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// lets create the object with name and url of the image and save this object into our database.
// String name_of_event = file_name.getText().toString().trim();
// String url_of_image = taskSnapshot.getMetadata().getReference().getDownloadUrl().toString();
// Upload upload = new Upload(name_of_event, url_of_image);
//Now you just need to get the url of the image that you have uploaded.
Task<Uri> uri = taskSnapshot.getStorage().getDownloadUrl();
while (!uri.isComplete()) ;
String url = uri.getResult().toString();
createUserEvent.setImageUrl(url);
//now we will save this object in our database
String uploadId = databaseReference.push().getKey();
Log.d(TAG, "onSuccess: Going To Save Object To Firebase");
Log.d(TAG, "onSuccess: UPLOAD ID : "+uploadId);
databaseReference.child("Event Details").child(uploadId).setValue(createUserEvent).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(context, "Data uploaded successfully", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, "Failed to upload data", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
}
});
} else {
progressDialog.dismiss();
Toast.makeText(context, "No File Selected", Toast.LENGTH_SHORT).show();
}
}
I am getting success while uploading to database. Please check your database now.
StorageReference filepath=storageReference.child("Blogimage").child(System.currentTimeMillis()+ "." +getFileEXt(imageuri));
//uploadTask=filepath.putFile(imageuri);
filepath.putFile(imageuri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// String downlod = taskSnapshot.getMetadata().getReference().getDownloadUrl().toString();
if (taskSnapshot.getMetadata() != null) {
if (taskSnapshot.getMetadata().getReference() != null) {
Task<Uri> result = taskSnapshot.getStorage().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String imageUrl = uri.toString();
DatabaseReference newpost=databaseReference.push();
Map<String , String > profile =new HashMap<>();
profile.put("name",name);
profile.put("prof",prof);
profile.put("location",location);
profile.put("email",mail);
profile.put("web",web);
profile.put("uid",user.getUid());
profile.put("url",imageUrl);
allUserMember.setName(name);
allUserMember.setUid(auth.getUid());
allUserMember.setProf(prof);
allUserMember.setLocation(location);
allUserMember.setUrl(imageUrl);
newpost.setValue(profile);
newpost.child(user.getUid()).setValue(allUserMember);
documentReference.set(profile).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Snackbar.make(findViewById(android.R.id.content),"Image uplode",Snackbar.LENGTH_LONG).show();
pd.dismiss();
Toast.makeText(CreateProfile1.this, "it work", Toast.LENGTH_SHORT).show();
}
});
//createNewPost(imageUrl);
}
});
}
}
i tried to do everything correctly and can't seem to find what's wrong here, i even created the project again from scratch but still it doesn't work, but i get the "failed" toast when trying to create an account, i added the internet permission too. i also don't get any error in logcat to show it here, how can this be solved ?
public class CreateAccountActivity extends AppCompatActivity {
private Button btnCreateAcc;
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener authStateListener;
private FirebaseUser currentUser;
// firestore
private FirebaseFirestore database = FirebaseFirestore.getInstance();
private CollectionReference collectionReference = database.collection("Users");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_account);
firebaseAuth = FirebaseAuth.getInstance();
authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
currentUser = firebaseAuth.getCurrentUser();
if (currentUser != null) {
} else {
}
}
};
btnCreateAcc = findViewById(R.id.create_acct_button);
btnCreateAcc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!TextUtils.isEmpty(etEmail.getText().toString()) &&
!TextUtils.isEmpty(etPassword.getText().toString()) &&
!TextUtils.isEmpty(etUserName.getText().toString())) {
String email = etEmail.getText().toString();
String password = etPassword.getText().toString();
String username = etUserName.getText().toString();
createUserEmailAccount(email, password, username);
} else {
Toast.makeText(CreateAccountActivity.this, "Please fill in all fields"
, Toast.LENGTH_SHORT).show();
}
}
});
}
private void createUserEmailAccount(String email, String password, final String username) {
if (!TextUtils.isEmpty(email) && !TextUtils.isEmpty(password) &&
!TextUtils.isEmpty(username)) {
progressBar.setVisibility(View.VISIBLE);
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
currentUser = firebaseAuth.getCurrentUser();
assert currentUser != null;
final String currentUserId = currentUser.getUid();
Map<String, String> userObj = new HashMap<>();
userObj.put("userId", currentUserId);
userObj.put("username", username);
collectionReference.add(userObj)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
documentReference.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (Objects.requireNonNull(task.getResult()).exists()) {
progressBar.setVisibility(View.INVISIBLE);
String name = task.getResult()
.getString("username");
Intent intent = new Intent(CreateAccountActivity.this,
PostJournalActivity.class);
intent.putExtra("username", name);
intent.putExtra("userId", currentUserId);
startActivity(intent);
} else {
progressBar.setVisibility(View.INVISIBLE);
}
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(CreateAccountActivity.this, "failed"
, Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(CreateAccountActivity.this, "failed task"
, Toast.LENGTH_SHORT).show();
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(CreateAccountActivity.this, "failed on complete"
, Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(this, "failed else", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onStart() {
super.onStart();
currentUser = firebaseAuth.getCurrentUser();
firebaseAuth.addAuthStateListener(authStateListener);
}
}
i fixed, the problem was i had allow read, write: if false; in firestore
and it needed to be allow read, write: if true;
This could be solved by following good debugging practices.
Meaningful error messages
When you encounter an error and wish to send a toast/alert to the user, send something meaningful to inform them what went wrong. As an example, instead of "failed" or "failed task", use "failed to upload user data" or "failed to create new user".
Each function will normally return a handful of exception classes that can be used to provide a better toast/alert message. Consulting the documentation for createUserWithEmailAndPassword(email, password) you can see what exceptions are thrown and use instanceof to determine the cause of the problem. For example, if e instanceof FirebaseAuthInvalidCredentialsException was true, you could toast "failed to create new user: invalid email".
While this seems tedious, it will save head-scratching later when a user encounters a problem and sends you a bug report/email about it. These steps will help you find any issues without needing access to logs for trivial problems such as incorrectly filled forms.
Log exceptions
The reason you have no information on what went wrong is because you haven't made use of the exception provided in each onFailure handler (public void onFailure(#NonNull Exception e) { ... }). These handlers provide you with the exception that caused the problem which you can save to the log using Log.e("yourActivityName:yourFunctionName", "short message", e). You can also use e.getMessage() to get information about the thrown error.
In an onComplete(Task<?> task) handler, if task.isSuccessful() returns false, you can find out why it is false by calling Exception e = task.getException() and then log it.
Fail-fast programming
If you ever find that you have an if-else pair where the if section contains lots more code than the else section, it is likely to be a sign that you should flip the condition.
Whilst keeping your code cleaner by using less indentation, it also avoids having to scroll through a long if that probably contains more if and else statements.
For example,
if (!requiredVariable1.isEmpty() && !requiredVariable2.isEmpty()) {
// ...
// many (nested) lines of code
// ...
} else {
Log.e(TAG, "a required variable was empty");
}
if (requiredVariable1.isEmpty() || requiredVariable2.isEmpty()) {
Log.e(TAG, "a required variable was empty");
return;
}
// ...
// many lines of code
// ...
Example
As an example of applying these changes, I have made edits to the code you provided applying fail-fast techniques, simplifying error handling, logging exceptions, using OnSuccessListener and OnFailureListener instead of OnCompleteListener where appropriate,
private void createUserEmailAccount(String email, String password, final String username) {
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password) || TextUtils.isEmpty(username)) {
Toast.makeText(this, "Please fill in all fields", Toast.LENGTH_SHORT).show();
return;
}
progressBar.setVisibility(View.VISIBLE);
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(#NonNull Task<AuthResult> task) {
currentUser = firebaseAuth.getCurrentUser();
assert currentUser != null;
final String currentUserId = currentUser.getUid();
Map<String, String> userObj = new HashMap<>();
userObj.put("userId", currentUserId);
userObj.put("username", username); // unknown source for variable: username
collectionReference.add(userObj)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
documentReference.get() // why redownload from database? you could just use values of "userObj"
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
progressBar.setVisibility(View.INVISIBLE);
if (!task.isSuccessful()
|| !Objects.requireNonNull(task.getResult()).exists()) {
// show a error message?
return;
}
String name = task.getResult()
.getString("username");
Intent intent = new Intent(CreateAccountActivity.this,
PostJournalActivity.class);
intent.putExtra("username", name);
intent.putExtra("userId", currentUserId);
startActivity(intent);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(CreateAccountActivity.this, "failed to add user data"
, Toast.LENGTH_SHORT).show();
Log.e("CreateAccountActivity", "failed to add user data", e); // log error to logcat
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(CreateAccountActivity.this, "failed to create user"
, Toast.LENGTH_SHORT).show();
Log.e("CreateAccountActivity", "failed to create user", e); // log error to logcat
}
});
}
I want to give the user in my app the possibility to delete his account so when he clicks on the delete button a document gets deleted which contains all his informations. The name of the document is his displayName so I get this as a string but when I run the code you are seeing below I get a NullpointerException in this line:
String currentUsername = user.getDisplayName();
even though the displayName is not null.
Edit:
I found the solution on my own, see the answer below.
Here is my method:
btn_delete_account.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
deleteDocument();
}
}
});
}
});
...
public void deleteDocument (){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String currentUsername = user.getDisplayName();
db.collection("User").document(currentUsername)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
Toast.makeText(PersonalSettings.this, "Your account was successfully deleted.", Toast.LENGTH_SHORT).show();
Intent i = new Intent(PersonalSettings.this, SignInActivity.class);
startActivity(i);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
First thing you have to check that current user is not null
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user==null)
{
return;
}
if current user is not null then get its name and further check that it's name is not null.
String currentUsername = user.getDisplayName();
if(TextUtils.isEmpty(currentUsername))
{
return;
}
if name is not null then go for delete document as follows :
public void deleteDocument (){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user==null)
{
return;
}
String currentUsername = user.getDisplayName();
if(TextUtils.isEmpty(currentUsername))
{
return;
}
db.collection("User").document(currentUsername)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
Toast.makeText(PersonalSettings.this, "Dein Account wurde erfolgreich gelöscht.", Toast.LENGTH_SHORT).show();
Intent i = new Intent(PersonalSettings.this, SignInActivity.class);
startActivity(i);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
I think you're misunderstanding the error. It's saying that user is null, not the display name. This means there is currently no user signed into the app. You will have to write some code to check for this case.
I also strongly suggest not using a display name as the ID for a document in Cloud Firestore. Since you're using Firebase Authentication, the user already has a unique ID assigned to their account. This is the preferred way to store per-user data.
I found the error:
I called my delete method after I used the user.delete() method which deletes the signed in user, so logically the displayName was also deleted.
How can I push the download URL of Firebase storage files to the Firestore cloud? I have a project that can upload PDF files to Firestore storage, but I can't push the download URL of the uploaded files to the Firestore cloud.
I need to catch the upload URL for every single file and send it to the document in the firestore to be able to download it. I'm uploading and downloading PDF files.
Here is my code:
public class pdfUploader extends AppCompatActivity {
private StorageReference mStorageRef;
Button upload;
Button select;
int CODE=215;
private CollectionReference dbFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_uploader);
mStorageRef = FirebaseStorage.getInstance().getReference();
upload = findViewById(R.id.upload);
select = findViewById(R.id.choose);
select.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectFile();
}
});
}
public void selectFile () {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i,"Select a file"), CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String filePath = data.getDataString();
Uri SelectedFileLocation=Uri.parse(filePath);
UploadFile(SelectedFileLocation);
super.onActivityResult(requestCode, resultCode, data);
}
public void UploadFile( Uri file) {
Toast.makeText(this, "Please wait.. the file is uploading!", Toast.LENGTH_SHORT).show();
//Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg"));
StorageReference riversRef = mStorageRef.child(Objects.requireNonNull(file.getLastPathSegment()));
riversRef.putFile(file)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(pdfUploader.this, "Upload Success", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(pdfUploader.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
});
}
}
Assign this Variable on Top
FirebaseFirestore db;
//In oncreateView we have to assign now db so.
db = FirebaseFirestore.getInstance();
Code for get File uri :
riversRef.putFile(File).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
riversRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Uri downloadUrl = uri;
Toast.makeText(MtActivity.this, "Upload Done", Toast.LENGTH_LONG).show();
//After upload Complete we have to store the Data to firestore.
Map<String, Object> file = new HashMap<>();
file.put("url", downloadUrl.toString()); // We are using it as String because our data type in Firestore will be String
db.collection("/*Put you're collection name*/").document("/*And Document name Here*/")
.set(file)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
}
}
});
If download url expires there's better way to store you're image file in you're storage and firestore
Code :
riversRef.putFile(file)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
String path = //Put path of storage it will be something like [images/filename.jpg(Put your extension of file)] this path from firebase storage
Map<String, Object> file = new HashMap<>();
file.put("url", path); // We are using it as String because our data type in Firestore will be String
db.collection("/*Put you're collection name*/").document("/*And Document id Here*/")
.set(file)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(pdfUploader.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
});
the above code will be useful and better when you're dealing with images and read this docs for further details
I'm trying learn Android Firebase. When I program a code of Register user, it work successfully. But when I called "userProfileChangeRequest" method
to change username OR profile picture uri it is work successfully, but new data isn't view to user before he log out and sign in again.
Why? What is the problem?
Here is my code:
private void getUriPicture() {
if(uriImage == null){
//user didn't select profile picture
return;
}
else if(!App.isOnline(this)) {
Toast.makeText(this, getResources().getString(R.string.checkInternetConnection), Toast.LENGTH_SHORT).show();
return;
}else{
mStorage = FirebaseStorage.getInstance().getReference();
//upload picture to get Path
Log.e(TAG,"test3");
StorageReference path = mStorage.child("ProfilePicture").child(uriImage.getLastPathSegment()
+ "_"
+ App.randomNumber()
+ "_"
+ App.randomNumber());
Log.e(TAG,"test4"+path);
path.putFile(uriImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.e(TAG,"Upload success");
#SuppressWarnings("VisibleForTests") Uri downloadUrl= taskSnapshot.getDownloadUrl();
//Preview profile picture before set it to user
Picasso.with(Setting.this).load(downloadUrl).into(profilePicture);
setUserProfilePicture(downloadUrl);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
TF=false;
Toast.makeText(Setting.this, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
private void setUserProfilePicture(Uri downloadUrl) {
//mProgress.setMessage(getResources().getString(R.string.updateProfile));
FirebaseUser user = mAuth.getCurrentUser();
if(user != null) {
Log.e(TAG,"test6");
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setPhotoUri(downloadUrl)
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.e(TAG, "Update Profile Successful");
Toast.makeText(Setting.this, getResources().getString(R.string.updateSuccessful), Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Update Failure");
Toast.makeText(Setting.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
Maybe you could try to update the user image in UI inside onCompleteListener ? As there are no view update actions done after you UserProfileChangeRequest.