I'm trying to add the data entered by the user into the realtime database, but it stops working and doesn't commit data. The image gets stored in the firebase storage, but data isn't getting saved in realtime and the activity closes and moves back to the previous activity.
This the code in the activity file:
pst.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final StorageReference reference = storage.getReference().child("compan")
.child(compName.getText().toString())
.child(new Date().getTime()+"");
reference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(addPost.this, "Post added", Toast.LENGTH_SHORT).show();
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
postModel po = new postModel();
po.setPostImg(uri.toString());
po.setPostedBy(FirebaseAuth.getInstance().getUid());
po.setPostDescr(descrip.getText().toString());
po.setPostId(new Date().getTime()+"");
database.getReference().child("Company").child(compName.getText().toString())
.push()
.setValue(po).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(addPost.this, "Post added", Toast.LENGTH_SHORT).show();
}
});
}
});
}
});
}
});
On trying a lot I got the following error in the logcat:
enter image description here
Am I missing something? I don't know what to do as the storage and authentication works fine.
Please check the database object, it seems it hasn't been initialized before using:
database = ... // initialize somehow
database.getReference().child("Company").child(compName.getText().toString())
...
Related
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 ?
I wrote the following code that deletes two documents from the cloud Firebase database:
fireDB.document(groupPath).collection("users").document(phoneNumber).delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
fireDB.collection("users").document(phoneNumber).delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(this.getClass().getName(), "DocumentSnapshot successfully deleted");
Toast.makeText(getApplicationContext(),R.string.successfully_deleted_user,Toast.LENGTH_LONG).show();
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(this.getClass().getName(), "Error deleting document", e);
Toast.makeText(getApplicationContext(),R.string.failed_to_delete_user,Toast.LENGTH_LONG).show();
}
});
Log.d(this.getClass().getName(), "DocumentSnapshot successfully deleted");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(this.getClass().getName(), "Error deleting document", e);
Toast.makeText(getApplicationContext(),R.string.failed_to_delete_user,Toast.LENGTH_SHORT).show();
}
});
The problem with that code is that it deletes first document and then deletes second document, meaning if the first try will delete it successfully and the second one will fail to delete it, there is going to be a problem. Is it possible to delete two documents in Firebase cloud database so the result could be of of the following two options:
Both of the documents are deleted.
Both of the document are not deleted.
Is it possible to do?
As robsiemb commented, you'll want to use a batch write or transaction for this.
As far as I can see, the equivalent from your code would be something like this:
// Get a new write batch
WriteBatch batch = db.batch();
DocumentReference docRef1 = fireDB.document(groupPath).collection("users").document(phoneNumber);
DocumentReference docRef2 = fireDB.collection("users").document(phoneNumber)
DocumentReference laRef = db.collection("cities").document("LA");
batch.delete(docRef1);
batch.delete(docRef2);
// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
// ...
}
});
I have realtime database in firebase it look like this
Now I want to delete value by key in android (java).
I have tried this code
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("coating").child("88").removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(activity, "on success", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(activity, "on success"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I get success response in onSuccess Method but value in database is not deleted.
As per this document
check out last para about delete and update ui
This is how I upload the image to Firebase storage.
Every time the app opens, I want to fetch image from storage and display in new activity.
StorageReference childRef=mStorage.child(newsnow).child("image3");
UploadTask uploadTask=childRef.putFile(uri3);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(PostNews.this, "uploaded", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(PostNews.this, "no da", Toast.LENGTH_SHORT).show();
}
});
For retrieving an image from firebase you have to store image URL in your Firebase database. After retrieving an image URL you can use libraries like Picasso, glide and so many others for getting an image from URL. You can prefer this link for more description.
Something like this should to the trick:
ImageView image = (ImageView) findViewById(R.id.image_placeholder);
childRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.with(MainActivity.this).load(uri).fit().centerCrop().into(image);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
Where image with R.id.image_placeholder is the place where you would like the image to be displayed.
Note that childRef is initialized in the same way that is now in your posted code.
I am doing this Android Project in which i want help in retrieving all the URLs which are stored in Firebase Storage and display them all in imageview. The Problem with the given code is that it only fetches one download url.In what way can i get all the URLs for all the images stored in Firebase.
In short: There is one activity in which I am saving the images to firebase and in other i want to retrieve all the images in Imageview.In what way i can do it ?
Thanks
if(requestCode== GALLERY_INTENT && resultCode== RESULT_OK)
{
mProgress.setMessage("Uploading....");
mProgress.show();
Uri uri =data.getData();
StorageReference filepath = mStorage.child("Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgress.dismiss();
Uri downloadUri = taskSnapshot.getDownloadUrl();
Picasso.with(MainActivity.this).load(downloadUri).fit().centerCrop().into(mImageView);
Toast.makeText(MainActivity.this,"Upload done",Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this,"Upload failed",Toast.LENGTH_LONG).show();
}
});
}
I don't think there is an API to fetch all files stored in firebase storage.
When i was saving files , i used to store the file metadata including the file name, download url etc in the real time database.
So when i had to fetch all the files from the storage, i would use the database.
Edit :
Here is how i did it.
UploadTask uploadTask = storageRef.putBytes(data,storageMetadata);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//Save to database using
//taskSnapshot.getMetadata().getCustomMetadata(StringKeys.SOME_KEY);
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
}
});
In Firebase, currently there are no API call that can give you list of all files in Firebase Storage. Instead what you can do is, Once image is uploaded to Firebase Storage, get the download link of that image using getDownloadUrl(); and save it to real-time database.
To read or write data from the database, you need an instance of DatabaseReference:
private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
To save link of the uploaded image to real time database, you need to create java object such as:
public class Image implements Serializable {
public String downloadUrl;
public Image() {
}
public Image(String dUrl) {
this.downloadUrl = dUrl;
}
}
Once you created java object, Add following lines of code in onSuccess(UploadTask.TaskSnapshot taskSnapshot):
Uri downloadUri = taskSnapshot.getDownloadUrl();
Image image = new Image(downloadUri.toString());
String userId = databaseReference.push().getKey();
databaseReference.child(userId).setValue(image);
This will add download link of that image in real-time database.
Now when you want list of all the images in your Firebase Storage, simply use the following code:
private ArrayList<Data> list;
...
private void getImagesList() {
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
Data data = new Data(childSnapshot.child("downloadUrl").getValue().toString());
list.add(data);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}