Firebase in Android, Storage is working but Database isn't - android

I'm trying to store an image with some relevant data regarding that image in Firebase. When I press the save button, the image is saved into my storage folder no problem, but the Database attributes just aren't being saved and I can't figure out why.
This is my code:
String Storage_Path = "All_Book_Images";
String Database_Path = "All_Books";
Uri FilePathUri;
StorageReference storageReference;
DatabaseReference databaseReference;
int Image_Request_Code = 71;
ProgressDialog progressDialog;
Button imageButton, saveButton;
EditText title, author, price, category, additionalInfo;
ImageView SelectImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bookupload);
SelectImage = (ImageView) findViewById(R.id.book_image);
title = (EditText) findViewById(R.id.title_text);
author = (EditText) findViewById(R.id.author_text);
price = (EditText) findViewById(R.id.price_text);
category = (EditText) findViewById(R.id.category_text);
additionalInfo = (EditText) findViewById(R.id.info_text);
storageReference = FirebaseStorage.getInstance().getReference();
databaseReference = FirebaseDatabase.getInstance().getReference(Database_Path);
}
public void imageButton(View view){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Image"),0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0 && resultCode == RESULT_OK){
FilePathUri = data.getData();
try{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), FilePathUri);
SelectImage.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getActualImage(Uri uri){
ContentResolver contentResolver = getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
}
public void uploadData(View view){
if(FilePathUri != null){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading");
progressDialog.show();
StorageReference reference = storageReference.child(Storage_Path + System.currentTimeMillis() + "." + getActualImage(FilePathUri));
reference.putFile(FilePathUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
String Title = title.getText().toString();
String Author = author.getText().toString();
String Price = price.getText().toString();
String Category = category.getText().toString();
String AdditionalInfo = additionalInfo.getText().toString();
Book book = new Book(taskSnapshot.getDownloadUrl().toString(), Title, Author, Price, Category, AdditionalInfo);
String id = databaseReference.push().getKey();
databaseReference.child(id).setValue(book);
progressDialog.dismiss();
Toast.makeText(getApplicationContext(),"Data uploaded",Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#SuppressWarnings("VisibleForTests")
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double totalProgress = (100*taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressDialog.setMessage("Uploaded % " + (int)totalProgress);
}
});
} else {
// show message
Toast.makeText(getApplicationContext(),"Please select data first",Toast.LENGTH_LONG).show();
}
}
What's causing this to interact with the Storage aspect of Firebase fine, but not the Database?

Check this snippet from Firebase Official Doc, i have writen some of your requirement inside, but you get the idea
private void writeNewPost(String Title, String Price, String Author) {
String key = databaseReference.push().getKey();
Post post = new Post(Title, Price, Author);
Map<String, Object> postValues = post.toMap();
Map<String, Object> books = new HashMap<>();
books.put(Title, postValues);
books.put(Price, postValues);
books.put(Author, postValues);
mDatabase.child(key).updateChildren(books);
}
for more info : https://firebase.google.com/docs/database/android/read-and-write
PS: you can use updateChildren() or setValue() , it depends which one you need.
If you use setValue() in this way, the data is overwritten at the specified location, including the secondary nodes.
You can make simultaneous updates to multiple locations in the JSON tree with a single call to updateChildren().

It turns out that my code was actually working OK, I just had the rules of my Firebase Database set up incorrectly. The code I posted in the question should work for anyone trying to implement this.

Related

firebase storage not created new folder at child android

I tried create folder per user by unique value (auth UID).
I did:
private String profileId;
private StorageReference mStorageRef;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
profileId = bundle.getString(Constants.PROFILE_ID_KEY);
mStorageRef = FirebaseStorage.getInstance().getReference("images");
StorageReference imageStorageRef = mStorageRef.child(profileId);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageName = "img" + timeStamp + "_.jpg";
imageStorageRef.child(imageName).putFile(picUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getUploadSessionUri();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
It is put all the images into specific profileId even when I sign out and connect with other profileId.
any help will be appraised
Your passing Constant Profile id : profileId = bundle.getString(Constants.PROFILE_ID_KEY);
Instead of just get user directly by using firebase auth.
if(FirebaseAuth.getInstance().getCurrentUser() != null){
uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
}else{
//do what you want
}

firebase / glide creating a reference of a image and displaying it

I am attempting to have the user upload an image and then have it then displayed as a profile picture. I am able to upload the image to firebase successfully but I am not able to display it I am following this thread
The current problem i am facing is on how to successfully get the image url to be able to display it
the current state of the code
private DatabaseReference mUserDatabase;
private FirebaseUser mCurrentUser;
//Android Layout
private CircleImageView mDisplayImage;
private TextView mName;
private TextView mStatus;
private Button mStatusBtn;
private Button mImageBtn;
private ProgressDialog mProgressDialog;
private static final int GALLERY_PICK = 1;
private StorageReference mImageStorage;
private Context context = user_profile.this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_profile);
mDisplayImage = (CircleImageView) findViewById(R.id.profile_picture);
mName = (TextView) findViewById(R.id.profile_user_name);
mStatus = (TextView) findViewById(R.id.profile_user_status);
mStatusBtn = (Button) findViewById(R.id.profile_change_status_btn);
mImageBtn = (Button) findViewById(R.id.profile_change_image_btn);
mImageStorage = FirebaseStorage.getInstance().getReference();
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
String current_uid = mCurrentUser.getUid();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_uid);
mUserDatabase.keepSynced(true);
mUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = Objects.requireNonNull(dataSnapshot.child("name").getValue()).toString();
String status = Objects.requireNonNull(dataSnapshot.child("status").getValue()).toString();
String image = Objects.requireNonNull(dataSnapshot.child("image").getValue()).toString();
mName.setText(name);
mStatus.setText(status);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mStatusBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String status_value = mStatus.getText().toString();
Intent status_intent = new Intent(user_profile.this, change_status.class);
status_intent.putExtra("status_value", status_value);
startActivity(status_intent);
}
});
mImageBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent, "Select Image"), GALLERY_PICK);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {
String imageUri = data.getDataString();
CropImage.activity(Uri.parse(imageUri))
.setAspectRatio(1, 1)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
mProgressDialog = new ProgressDialog((user_profile.this));
mProgressDialog.setTitle("Uploading");
mProgressDialog.setMessage("Pleas Stand By");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
Uri resultUri = result.getUri();
String current_user_id = mCurrentUser.getUid();
StorageReference filepath = mImageStorage.child("profile_images").child(current_user_id + (".jpeg"));
filepath.putFile(resultUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
final String download_url = Objects.requireNonNull(task.getResult()).getStorage().getDownloadUrl().toString();
mUserDatabase.child("image").setValue(download_url).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Glide
.with(context)
.load()
.into(mDisplayImage);
mProgressDialog.dismiss();
Toast.makeText(user_profile.this, "Succesful Upload", Toast.LENGTH_LONG).show();
}
}
});
} else {
Toast.makeText(user_profile.this, "Error Up Loading", Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
}
});
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
}
}
}
public String niceRefLink (String date){
StorageReference storageRef = FirebaseStorage.getInstance().getReference();
StorageReference dateRef = storageRef.child("profile_images");
return dateRef.toString();
}}
I believe the issue is with this block of code
public String niceRefLink (String date){
StorageReference storageRef = FirebaseStorage.getInstance().getReference();
StorageReference dateRef = storageRef.child("profile_images");
return dateRef.toString();
}}
When the image is attempted to be displayed glide says that it is unable to locate the image this is how my database is looking
I tried to use the method niceRefLink to display the image but I was unsuccessful i have also tried the download_url string i have created but also did not work
HI, i tried the answer you submitted but I am still having issues the image is successfully getting uploaded to the database but it is still not getting displayed when i run the app i am getting the toast upload successful but the image stays as the preview image.
private String mImageUri;
private void getUserInfo(){
mUserDatabase.child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists() && dataSnapshot.getChildrenCount()>0){
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
if(map.get("image")!=null){
mImageUri = map.get("image").toString();
Glide.with(getApplication()).load(mImageUri).into(mDisplayImage);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
This code is, How to get image url and how to display in ImageView.
private void getUserInfo(){
mCustomerDatabase.child("Users").child(current_uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists() && dataSnapshot.getChildrenCount()>0){
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
if(map.get("image")!=null){
mProfileImageUrl = map.get("image").toString();
Glide.with(getApplication()).load(mProfileImageUrl).into(profileImage);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Hope it's help full and Enjoy.

how to show all image urls along with username, title, uid,timestamp in adapter class

I'm trying to show all image URLs along with username, timestamp, and title but only one image is showing. I'm using recyclerview adapter. I want to show all image URLs with a long title, timestamp, and username in adapter like one post
This is how I'm storing in firebase database using blog class
ArrayList<Uri> arrayListImageDownloadUri = new ArrayList<>();
final Uri downloaduri = taskSnapshot.getDownloadUrl();
Log.v("DOWNLOAD URI", String.valueOf(downloaduri));
blogimages.add(downloaduri.toString());
Log.v("BLOGGIMAGES", String.valueOf(blogimages));
// final String path= uri.getLastPathSegment();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("posts/");
final String newPostKey = ref.push().getKey();
final String posttitle = desc.getText().toString();
final String CurrentUser = firebaseAuth.getCurrentUser().getUid();
userid = FirebaseDatabase.getInstance().getReference().child("Blog").child(CurrentUser).push();
ArrayList<String> arrayList = new ArrayList<>();
for(int i=0; i<blogimages.size();i++) {
arrayList.add( blogimages.get(i).toString());
Log.v("IMAGESADDING PHSE3", String.valueOf(arrayList));
}
Log.v("COCOCOCOCO", String.valueOf(arrayList));
n.put(String.valueOf("img"), blogimages.get(i).toString());*/
Blog blog = new Blog();
long millis = System.currentTimeMillis();
int timestamp = ((int) (millis/1000))* -1;
blog.setTitle(posttitle);
blog.setUrl(arrayList);
blog.setUid(firebaseAuth.getCurrentUser().getUid());
mdatabaseReference.child(CurrentUser).setValue(blog)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Intent mm = new Intent(PhotoUploadActivity.this, MainActivity.class);
startActivity(mm);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(PhotoUploadActivity.this, "Failed to post the blog.. Try again later", Toast.LENGTH_LONG).show();
}
});
you can use this in on success listener when you get blog data:
rootRef.child("Blog").child("blogId").child(url).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
urlList.add(dataSnapshot.getValue()); //you will receive single element
//every time in this listener you can store it in list then you can give it to your adapter out side this listener
}
...
NOTE: you must implement method on Child Changed,Removed...

Android Firebase multiple image upload

I am writing an app to test out firebase where a user can list a product with images.
I'm having issues with the upload as although the pictures are stored, they are not linked to the product (images array not being passed?) and LeakCanary signals an outofmemory error.
All help and input appreciated.
Here's my Product Model
#IgnoreExtraProperties
public class Product {
public String uid;
public String seller;
public String name;
public String description;
public String city;
public double price = 0.0;
public List<Uri> images = new ArrayList<>();
public Product () {
}
public Product(String uid, String seller, String name, String description, String city, double price, List<Uri> images) {
this.uid = uid;
this.seller = seller;
this.name = name;
this.description = description;
this.city = city;
this.price = price;
this.images = images;
}
// [START post_to_map]
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("uid", uid);
result.put("seller", seller);
result.put("name", name);
result.put("description", description);
result.put("city", city);
result.put("price", price);
result.put("images", images);
return result;
}
}
And here are is my AddProductActivity
public class AddProductActivity extends BaseActivity implements AddProductContract.View, View.OnClickListener {
private AddProductContract.Presenter mPresenter;
private Bitmap mBitmap;
private byte[] mByteArray;
private List<String> mPhotos;
private Button mPublishBtn;
private EditText mProductNameField;
private EditText mProductDescriptionField;
private EditText mProductPriceField;
private DatabaseReference mFirebaseDatabase;
private StorageReference mFirebaseStorage;
private StorageTask mUploadTask;
private List<Uri> uploadedImages = new ArrayList<>();
private LinearLayout mLinearLayout;
private ImageButton mImageButton;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
showEmptyImageError();
} else {
mPhotos = (List<String>) data.getSerializableExtra(GalleryActivity.PHOTOS);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_edit_product_2);
mFirebaseDatabase = FirebaseDatabase.getInstance().getReference();
mFirebaseStorage = FirebaseStorage.getInstance().getReference();
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
mToolbar.setTitle(R.string.addItemTextview);
mLinearLayout = (LinearLayout) findViewById(R.id.activity_add_product);
mLinearLayout.setOnClickListener(this);
mImageButton = (ImageButton) findViewById(R.id.imageButton);
mImageButton.setOnClickListener(this);
mPublishBtn = (Button) findViewById(R.id.publishItemBtn);
mPublishBtn.setOnClickListener(this);
mProductNameField = (EditText) findViewById(R.id.productNameField);
mProductDescriptionField = (EditText) findViewById(R.id.productDescriptionField);
mProductPriceField = (EditText) findViewById(R.id.priceField);
// mPresenter = new AddProductPresenter(this);
}
#Override
public void onClick(View view) {
if ((view == mLinearLayout)) {
hideKeyboard();
} else if (view == mImageButton) {
GalleryConfig config = new GalleryConfig.Build()
.limitPickPhoto(8)
.singlePhoto(false)
.hintOfPick("You can pick up to 8 pictures.")
.filterMimeTypes(new String[]{"image/*"})
.build();
GalleryActivity.openActivity(AddProductActivity.this, 2, config);
} else if (view == mPublishBtn) {
final String name = mProductNameField.getText().toString();
final String description = mProductDescriptionField.getText().toString();
final double price = Double.parseDouble(mProductPriceField.getText().toString());
setPublishingEnabled(false);
showErrorToast(getResources().getString(R.string.publishing));
final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
mFirebaseDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user == null) {
showErrorToast(getResources().getString(R.string.empty_user));
} else {
publishProduct(userId, user.getUsername(), name, description,
user.getCity(), price, mPhotos);
}
setPublishingEnabled(true);
finish();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("AddProductActivity", "getUser:onCancelled", databaseError.toException());
setPublishingEnabled(true);
}
}
);
}
}
private void setPublishingEnabled(boolean enabled) {
if (enabled) {
mPublishBtn.setVisibility(View.VISIBLE);
} else {
mPublishBtn.setVisibility(View.GONE);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void showEmptyImageError() {
Toast.makeText(getApplicationContext(), R.string.empty_image_error, Toast.LENGTH_SHORT).show();
}
private void publishProduct(String userId, String seller, String name, String description,
String city, double price, List<String> images) {
for (String photo : images) {
Uri file = Uri.fromFile(new File(photo));
StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
mUploadTask = photoRef.putFile(file);
mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
uploadedImages.add(downloadUrl);
}
});
}
String key = mFirebaseDatabase.child("products").push().getKey();
Product product = new Product(userId, seller, name, description, city, price, uploadedImages);
Map<String, Object> productValues = product.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/products/" + key, productValues);
childUpdates.put("/user-products/" + userId + "/" + key, productValues);
mFirebaseDatabase.updateChildren(childUpdates);
}
//
// private List<Uri> uploadPhotos(List<String> input) {
// images = new ArrayList<>();
// Observable.just(input)
// .map(this::doInBackground)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .doOnSubscribe(this::onPreExecute)
// .subscribe(this::onPostExecute);
// return images;
// }
//
// private void onPreExecute() {
// Log.i("Start time", "SET");
// Toast.makeText(this, R.string.image_formatting_toast, Toast.LENGTH_SHORT).show();
// }
//
// private List<Uri> doInBackground(List<String> photos) {
// for (String photo : mPhotos) {
// Uri file = Uri.fromFile(new File(photo));
// StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
// mUploadTask = photoRef.putFile(file);
//
// mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
// .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
// #Override
// public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Uri downloadUrl = taskSnapshot.getDownloadUrl();
// images.add(downloadUrl);
// }
// });
// }
// return images;
// }
//
// private void onPostExecute(List<Uri> uriSet) {
// Toast.makeText(this, R.string.product_visibility_toast, Toast.LENGTH_SHORT).show();
// Log.i("End time", "SET");
// }
}
Trying to understand your code flow, I can see one thing:
inside your publishProduct method you should put the code (to update the childeren in Firebase) into the addOnSuccessListener, like this:
private void publishProduct(String userId, String seller, String name, String description,
String city, double price, List<String> images) {
String key = mFirebaseDatabase.child("products").push().getKey();
for (String photo : images) {
Uri file = Uri.fromFile(new File(photo));
StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
mUploadTask = photoRef.putFile(file);
mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
uploadedImages.add(downloadUrl);
Product product = new Product(userId, seller, name, description, city, price, uploadedImages);
Map<String, Object> productValues = product.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/products/" + key, productValues);
childUpdates.put("/user-products/" + userId + "/" + key, productValues);
mFirebaseDatabase.updateChildren(childUpdates);
}
});
}
}
And, if you want to know if the updateChildren operation is completed or not, add the onComplete and onFailure listeners, like this:
mFirebaseDatabase.updateChildren(childUpdates).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
Update
I think you can try to change your database structure, removing the list of images from the product's nodes, adding instead a node in your database that will store only the list of images associated with each product:
"/product-images/" + yourKey + "/" + imageKey
contains the list of his images. imageKey is different from one image the another (it could be for example the image name). yourKey could be the userId or the key associated with each product, it depends on how the database is structured. Then, you can try to use setValue instead of updateChildren into your OnSuccessListener, something like this:
mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
mFirebaseDatabase.child("product-images").child(yourKey).child(imageKey).setValue(downloadUrl.toString());
}
});
Hope this helps!

Android Firebase - Updating new image to current user stops the application (not crash)

I was trying to change profile picture by clicking an imageview and I was able to crop the image then store into my Firebase storage. But, when the new image file is added, the program stops and cant click anything. App is not even crashing nor turned off. and when I see my android monitor it is keep printing something out nonstop. I think this goes into some sort of infinite loop somewhere. Does anyone recognize the problem?
P.S. When I update new profile image, I see that the image child under my User in my Firebase database changes really fast, back and forth. If the previous image is "1" and the image I updated is "2", it goes 1->2->1->2->1->2.. like crazy. They swap each other very fast
MyProfileActivity.java
public class MyProfileActivity extends AppCompatActivity
{
/*UI*/
private Toolbar mMyProfileToolbar;
private TextView mAge;
private TextView mGender;
private TextView mReligion;
private TextView mSports;
private TextView mState;
private TextView mTimeRegistered;
private TextView mDisplayName;
private CircleImageView mProfileImage;
/*Firebase*/
private DatabaseReference mDatabaseUser;
private FirebaseUser mUser;
private StorageReference mStorage;
private DatabaseReference mDatabasePost;
private StorageReference filepath;
private DatabaseReference user_db;
/*Other*/
private String age;
private String gender;
private String religion;
private String sports;
private String state;
private String timeRegistered;
private String displayName;
private String image;
private Uri mImageUri = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_profile);
/*UI*/
mMyProfileToolbar = (Toolbar)findViewById(R.id.activity_my_profile_toolbar);
mProfileImage = (CircleImageView)findViewById(R.id.activity_my_profile_profile_image);
mDisplayName = (TextView)findViewById(R.id.activity_my_profile_display_name);
mAge = (TextView)findViewById(R.id.activity_my_profile_age);
mGender = (TextView)findViewById(R.id.activity_my_profile_gender);
mReligion = (TextView)findViewById(R.id.activity_my_profile_religion);
mSports = (TextView)findViewById(R.id.activity_my_profile_sports);
mState = (TextView)findViewById(R.id.activity_my_profile_state);
mTimeRegistered = (TextView)findViewById(R.id.activity_my_profile_time_registered);
/*Firebase*/
mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("User");
mUser = FirebaseAuth.getInstance().getCurrentUser();
mStorage = FirebaseStorage.getInstance().getReference();
/*Function*/
setSupportActionBar(mMyProfileToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(null);
mDatabaseUser.child(mUser.getUid()).addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
displayName = dataSnapshot.child("displayName").getValue().toString();
age = dataSnapshot.child("age").getValue().toString();
gender = dataSnapshot.child("gender").getValue().toString();
religion = dataSnapshot.child("religion").getValue().toString();
sports = dataSnapshot.child("sports").getValue().toString();
state = dataSnapshot.child("state").getValue().toString();
timeRegistered = dataSnapshot.child("timeRegistered").getValue().toString();
image = dataSnapshot.child("image").getValue().toString();
Picasso.with(MyProfileActivity.this).load(image).into(mProfileImage);
mDisplayName.setText(displayName);
mAge.setText("Age: " + age);
mGender.setText("Gender: " + gender);
mReligion.setText("Religion: " + religion);
mSports.setText("Sports: " + sports);
mState.setText("State: " + state);
mTimeRegistered.setText("Time Registered: " + timeRegistered);
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
mProfileImage.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("image/*");
startActivityForResult(i, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode == RESULT_OK)
{
mImageUri = data.getData();
CropImage.activity(mImageUri)
.setGuidelines(CropImageView.Guidelines.OFF)
.setAspectRatio(1, 1)
.start(this);
}
if(requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE)
{
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if(resultCode == RESULT_OK)
{
mImageUri = result.getUri();
mProfileImage.setImageURI(mImageUri);
filepath = mStorage.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("Profile_Images").child(mImageUri.getLastPathSegment());
filepath.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
{
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
final Uri downloadUrl = taskSnapshot.getDownloadUrl();
Toast.makeText(MyProfileActivity.this, "You added picture successfully", Toast.LENGTH_SHORT).show();
mDatabaseUser.child(mUser.getUid()).addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Toast.makeText(MyProfileActivity.this, "Changing picture now", Toast.LENGTH_SHORT).show();
DatabaseReference user_db = mDatabaseUser.child(mUser.getUid());
user_db.child("image").setValue(downloadUrl.toString());
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
}
});
}
else if(resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE)
{
Exception error = result.getError();
}
}
}
}
Your app is looping in the code shown below. You add a listener to location mDatabaseUser.child(mUser.getUid()). When the data at that location changes, onDataChange() runs and performs a setValue() for child image of location mDatabaseUser.child(mUser.getUid()). Although you are only changing a child of the location, it is considered a change to the parent location, causing the listener to fire again, setting the value again, and so on, endlessly.
mDatabaseUser.child(mUser.getUid()).addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Toast.makeText(MyProfileActivity.this, "Changing picture now", Toast.LENGTH_SHORT).show();
DatabaseReference user_db = mDatabaseUser.child(mUser.getUid());
user_db.child("image").setValue(downloadUrl.toString());
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
You also have two listeners on the same location, the one shown above and the second in the onCreate() method. Both listeners will fire when any part of the location changes.

Categories

Resources