Retrieving image from firebase shows same image multiple times - android

MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final String ANONYMOUS = "anonymous";
public static final int RC_SIGN_IN = 1;
private static final int RC_PHOTO_PICKER = 2;
private String mUsername;
// Firebase instance variables
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mMessagesDatabaseReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseStorage mFirebaseStorage;
private StorageReference mChatPhotosStorageReference;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private ProgressBar progressBar;
private RecyclerView recyclerView;
private FloatingActionButton floatingActionButton;
PhotosAdapter contactsAdapter;
List<Photos> contactList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar)findViewById(R.id.progressbar);
mUsername = ANONYMOUS;
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
floatingActionButton=(FloatingActionButton)findViewById(R.id.floatingactionbutton);
contactList = new ArrayList();
progressBar.setVisibility(View.GONE);
// Initialize Firebase components
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseStorage = FirebaseStorage.getInstance();
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
mMessagesDatabaseReference = mFirebaseDatabase.getReference().child("messages");
mChatPhotosStorageReference = mFirebaseStorage.getReference().child("chat_photos");
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
onSignedInInitialize(user.getDisplayName());
} else {
// User is signed out
onSignedOutCleanup();
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setProviders(
AuthUI.EMAIL_PROVIDER,
AuthUI.GOOGLE_PROVIDER)
.build(),
RC_SIGN_IN);
}
}
};
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);
}
});
mMessagesDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
if(!contactList.contains(imageUploadInfo)){
contactList.add(imageUploadInfo);
Log.i(TAG, "onDataChange: "+contactList);
}
}
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
progressBar.setVisibility(View.GONE);
recyclerView.setAdapter(contactsAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),5));
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
// Sign-in succeeded, set up the UI
Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// Sign in was canceled by the user, finish the activity
Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
finish();
}
}else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
// Get a reference to store file at chat_photos/<FILENAME>
StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());
// Upload file to Firebase Storage
photoRef.putFile(selectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// When the image has successfully uploaded, we get its download URL
// progressBar.setVisibility(View.VISIBLE);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
// Set the download URL to the message box, so that the user can send it to the database
Photos friendlyMessage = new Photos(downloadUrl.toString());
mMessagesDatabaseReference.push().setValue(friendlyMessage);
}
});
}
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null) {
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
}
}
private void onSignedInInitialize(String username) {
mUsername = username;
}
private void onSignedOutCleanup() {
mUsername = ANONYMOUS;
}
}
Suppose I upload an image to firebase storage, it gets retrieved in my imageview of recyclerview in app. When I upload second image, the first image gets displayed twice and second image once in my app. When I upload third image, first image gets displayed thrice, second image twice and third image once. I know the problem is in mMessagesDatabaseReference.addValueEventListener but I am not able to figure it out. Please help me..

I suppose that onDataChange will be called with all data at each new upload. So you have to clear contactList before adding items, like:
public void onDataChange(DataSnapshot snapshot) {
contactList.clear()
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
if(!contactList.contains(imageUploadInfo)){
contactList.add(imageUploadInfo);
Log.i(TAG, "onDataChange: "+contactList);
}
}
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
progressBar.setVisibility(View.GONE);
recyclerView.setAdapter(contactsAdapter);
}

use ChildEventListener instead of value event listener.
Value event listener fetches all the data again on a single change so for adding image 2, image 1 will also be received in value event.
In ChildEventListener there is method onChildAdded() where you add to your recycler.
Use the child event listener like this, no need of for loop, it will be called for when a child is added, avoiding need to do a loop
also after adding item don't forget to call notify on recyclerAdapter to show changes on view
Move these in onCreate method and intialize there:
contactList = new ArrayList();
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
recyclerView.setAdapter(contactsAdapter);
Code to get child from firebase
private void attachDatabaseReadListener() {
if (mChildEventListener == null) {
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Photos imageUploadInfo = dataSnapshot.getValue(Photos.class);
if (!contactList.contains(imageUploadInfo)) {
contactList.add(imageUploadInfo);
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
mMessagesDatabaseReference.addChildEventListener(mChildEvent‌​Listener);
}
}

Related

Trying to get image from firebase so that user can set profile image but its blank

Im trying to allow users to click on the image item and choose a picture from their galley. this picture should then be pushed to firebase and added to the image view automatically but it is showing up blank after I close the application. I have tried numerous methods but cant seem to get it working. here is where i implement everything:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
ImageView imageView;
public static final int IMAGE_CODE = 1;
Uri imageUri;
private StorageReference storageReference;
private DatabaseReference databaseReference;
FirebaseUser user;
String userid;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) headerView.findViewById(R.id.profilepic);
user = FirebaseAuth.getInstance().getCurrentUser();
userid = user.getUid();
storageReference = FirebaseStorage.getInstance().getReference("Images");
databaseReference = FirebaseDatabase.getInstance().getReference("uploads").child(userid);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openimage();
}
});
profileImage();
}
private void profileImage(){
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
Upload upload = dataSnapshot.getValue(Upload.class);
Glide.with(getApplicationContext()).load(upload.getUplaodUri()).into(imageView);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void openimage() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, IMAGE_CODE);
}
#TargetApi(Build.VERSION_CODES.M)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
checkPermission1();
} else {
// Do as per your logic
}
}
if (requestCode == IMAGE_CODE && resultCode == RESULT_OK && null != data && data.getData() != null) {
imageUri = data.getData();
Glide.with(this).load(imageUri).into(imageView);
fileUploader();
}
}
private String getFileExtension(Uri uri){
ContentResolver cr = getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(cr.getType(uri));
}
private void fileUploader(){
if(imageUri != null){
StorageReference reference = storageReference.child(userid + ".jpeg");
reference.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Upload upload = new Upload(uri.toString());
databaseReference.setValue(upload).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
profileImage();
}
});
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
;;
}
});
}else{
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
}
Database Structure
Edit:
2020-05-03 15:55:51.232 25230-25407/com.example.carcrashdetection E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2020-05-03 15:55:51.235 25230-25407/com.example.carcrashdetection E/StorageException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage##19.1.1:433)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage##19.1.1:450)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage##19.1.1:441)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage##19.1.1:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage##19.1.1:286)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage##19.1.1:70)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage##19.1.1:62)
at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage##19.1.1:76)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Also the image is in a navigation drawer and should be unique to each user. Can someone please tell me where I am going wrong?
You can do it like this:
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Upload upload = new Upload(uri.toString());
String uploadId = databaseReference.child(userid).push().getKey();
databaseReference.child(uploadId).setValue(upload);
}
});
Firebase Storage docs
And there is a problem in this line:
Glide.with(getApplicationContext()).load(upload).into(imageView);
upload is an object. You should use upload.getUploadUri()
if(dataSnapshot.exists()) {
for (DataSnapshot ds : dataSnapshot.getChildren()){
Upload upload = ds.getValue(Upload.class);
Glide.with(getApplicationContext()).load(upload.getUplaodUri()).into(imageView);
}
}
You always see last uploaded image this way. If a user has an image you don't need to use uploadId.
Profile image:
Upload upload = new Upload(uri.toString());
databaseReference.setValue(upload);
and:
if(dataSnapshot.exists()) {
Upload upload = dataSnapshot.getValue(Upload.class);
Glide.with(getApplicationContext()).load(upload.getUplaodUri()).into(imageView);
}
more useful for you.

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 retrieve image from firebase based on click

I am using Firebase for my android app. I have uploaded few images in Storage section of firebase and displayed in listview. Now when I click on particular image of recyclerview, I want to move to next activity and show the image which I clicked on in imageview of next activity. How to retrieve that particular image? Please help.
I have created a photos folder in storage of my firebase and all images are stored in that folder.
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final String ANONYMOUS = "anonymous";
public static final int DEFAULT_MSG_LENGTH_LIMIT = 1000;
public static final String FRIENDLY_MSG_LENGTH_KEY = "friendly_msg_length";
public static final int RC_SIGN_IN = 1;
private static final int RC_PHOTO_PICKER = 2;
private ListView mMessageListView;
private MessageAdapter mMessageAdapter;
private ProgressBar mProgressBar;
private ImageButton mPhotoPickerButton;
private EditText mMessageEditText;
private Button mSendButton;
private String mUsername;
// Firebase instance variables
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mMessagesDatabaseReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseStorage mFirebaseStorage;
private StorageReference mChatPhotosStorageReference;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUsername = ANONYMOUS;
// Initialize Firebase components
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseStorage = FirebaseStorage.getInstance();
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
mMessagesDatabaseReference = mFirebaseDatabase.getReference().child("messages");
mChatPhotosStorageReference = mFirebaseStorage.getReference().child("photos");
// Initialize references to views
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageListView = (ListView) findViewById(R.id.messageListView);
mPhotoPickerButton = (ImageButton) findViewById(R.id.photoPickerButton);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mSendButton = (Button) findViewById(R.id.sendButton);
// Initialize message ListView and its adapter
List<FriendlyMessage> friendlyMessages = new ArrayList<>();
mMessageAdapter = new MessageAdapter(this, R.layout.item_message, friendlyMessages);
mMessageListView.setAdapter(mMessageAdapter);
// Initialize progress bar
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
// ImagePickerButton shows an image picker to upload a image for a message
mPhotoPickerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);
}
});
// Enable Send button when there's text to send
mMessageEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(DEFAULT_MSG_LENGTH_LIMIT)});
// Send button sends a message and clears the EditText
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(), mUsername, null);
mMessagesDatabaseReference.push().setValue(friendlyMessage);
// Clear input box
mMessageEditText.setText("");
}
});
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
onSignedInInitialize(user.getDisplayName());
} else {
// User is signed out
onSignedOutCleanup();
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setProviders(
AuthUI.EMAIL_PROVIDER,
AuthUI.GOOGLE_PROVIDER)
.build(),
RC_SIGN_IN);
}
}
};
// Create Remote Config Setting to enable developer mode.
// Fetching configs from the server is normally limited to 5 requests per hour.
// Enabling developer mode allows many more requests to be made per hour, so developers
// can test different config values during development.
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
mFirebaseRemoteConfig.setConfigSettings(configSettings);
// Define default config values. Defaults are used when fetched config values are not
// available. Eg: if an error occurred fetching values from the server.
Map<String, Object> defaultConfigMap = new HashMap<>();
defaultConfigMap.put(FRIENDLY_MSG_LENGTH_KEY, DEFAULT_MSG_LENGTH_LIMIT);
mFirebaseRemoteConfig.setDefaults(defaultConfigMap);
fetchConfig();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
// Sign-in succeeded, set up the UI
Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// Sign in was canceled by the user, finish the activity
Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
finish();
}
} else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
// Get a reference to store file at chat_photos/<FILENAME>
StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());
// Upload file to Firebase Storage
photoRef.putFile(selectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// When the image has successfully uploaded, we get its download URL
Uri downloadUrl = taskSnapshot.getDownloadUrl();
// Set the download URL to the message box, so that the user can send it to the database
FriendlyMessage friendlyMessage = new FriendlyMessage(null, mUsername, downloadUrl.toString());
mMessagesDatabaseReference.push().setValue(friendlyMessage);
}
});
}
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null) {
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
}
mMessageAdapter.clear();
detachDatabaseReadListener();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sign_out_menu:
AuthUI.getInstance().signOut(this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void onSignedInInitialize(String username) {
mUsername = username;
attachDatabaseReadListener();
}
private void onSignedOutCleanup() {
mUsername = ANONYMOUS;
mMessageAdapter.clear();
detachDatabaseReadListener();
}
private void attachDatabaseReadListener() {
if (mChildEventListener == null) {
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class);
mMessageAdapter.add(friendlyMessage);
}
public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
public void onChildRemoved(DataSnapshot dataSnapshot) {}
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
public void onCancelled(DatabaseError databaseError) {}
};
mMessagesDatabaseReference.addChildEventListener(mChildEventListener);
}
}
private void detachDatabaseReadListener() {
if (mChildEventListener != null) {
mMessagesDatabaseReference.removeEventListener(mChildEventListener);
mChildEventListener = null;
}
}
// Fetch the config to determine the allowed length of messages.
public void fetchConfig() {
long cacheExpiration = 3600; // 1 hour in seconds
// If developer mode is enabled reduce cacheExpiration to 0 so that each fetch goes to the
// server. This should not be used in release builds.
if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
cacheExpiration = 0;
}
mFirebaseRemoteConfig.fetch(cacheExpiration)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// Make the fetched config available
// via FirebaseRemoteConfig get<type> calls, e.g., getLong, getString.
mFirebaseRemoteConfig.activateFetched();
// Update the EditText length limit with
// the newly retrieved values from Remote Config.
applyRetrievedLengthLimit();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// An error occurred when fetching the config.
Log.w(TAG, "Error fetching config", e);
// Update the EditText length limit with
// the newly retrieved values from Remote Config.
applyRetrievedLengthLimit();
}
});
}
/**
* Apply retrieved length limit to edit text field. This result may be fresh from the server or it may be from
* cached values.
*/
private void applyRetrievedLengthLimit() {
Long friendly_msg_length = mFirebaseRemoteConfig.getLong(FRIENDLY_MSG_LENGTH_KEY);
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(friendly_msg_length.intValue())});
Log.d(TAG, FRIENDLY_MSG_LENGTH_KEY + " = " + friendly_msg_length);
}
}
When you upload the image a download URL is created by Firebase.
From your code, it's clear that you have the image download URL as created by Firebase.
Even if you dont have the Download URL you can get it using the
storageReferenceObj.getDownloadUrl();
In order to load that image in an ImageView you can use the Picasso library.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
replace the URL with your download URL and specify your image view. But First add this line to your Gradle file in order to include Picasso library.
compile 'com.squareup.picasso:picasso:2.5.2'
More info: http://square.github.io/picasso/
Implement an onclick listener for the recycleview and pass the image URL in intent on the new activity as follows
intent.putExtra("IMAGE_URL", "url of the image");
startActivity(intent);
Use the following code to get the URL on the second activity
String url = getIntent().getStringExtra("IMAGE_URL");

In FCM, how can we send the push notification to the particular group of people and to single person?

I am making an android application in which i am using serverless FCM push notification. So, have to send two types of notification, first is a broadcast notification from a customer to all the registered shopkeepers within 1-2 km circumference of the current location of the customer, and the second one is the reply of the shopkeeper to that particular customer only. I am stuck with this code, not able to resolve the problem. My nodes.js and android code is below mentioned.
//import firebase functions modules
const functions = require('firebase-functions');
//import admin module
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// Listens for new messages added to messages/:pushId
exports.pushNotification = functions.database.ref('/messages/{pushId}').onWrite( event => {
console.log('Push notification event triggered');
// Grab the current value of what was written to the Realtime Database.
var valueObject = event.data.val();
if(valueObject.photoUrl != null) {
valueObject.photoUrl= "Sent you a photo!";
}
console.log('Push notification 1');
// Create a notification
const payload = {
notification: {
title:valueObject.name,
body: valueObject.text || valueObject.photoUrl,
sound: "default"
},
};
console.log('Push notification 2');
//Create an options object that contains the time to live for the notification and the priority
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
console.log('Push notification 3');
return admin.messaging().sendToTopic("pushNotifications", payload, options);
});
public class CloudMain extends BaseActivty {
public static final String ANONYMOUS = "anonymous";
public static final int DEFAULT_MSG_LENGTH_LIMIT = 10;
public static final int RC_SIGN_IN = 1;
private static final int RC_PHOTO_PICKER = 2;
private ListView mMessageListView;
private MessageAdapter mMessageAdapter;
private ProgressBar mProgressBar;
private ImageButton mPhotoPickerButton;
private EditText mMessageEditText;
private Button mSendButton;
private String mUsername;
private FirebaseDatabase mDatabase;
private DatabaseReference mMessagesReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseStorage mStorage;
private StorageReference mChatPhotosStorageRef;
private FirebaseUser user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cloud_main);
Intent intent = getIntent();
mDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mStorage = FirebaseStorage.getInstance();
FirebaseUser user = mFirebaseAuth.getCurrentUser();
String userId = user.getUid();
mUsername = user.getDisplayName() ; //ANONYMOUS;
mMessagesReference = mDatabase.getReference().child("users").child(userId).child("messages");
mChatPhotosStorageRef = mStorage.getReference().child("users").child(userId).child("chat_photos");
FirebaseMessaging.getInstance().subscribeToTopic("pushNotifications");
// Initialize references to views
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageListView = (ListView) findViewById(R.id.messageListView);
mPhotoPickerButton = (ImageButton) findViewById(R.id.photoPickerButton);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mSendButton = (Button) findViewById(R.id.sendButton);
// Initialize message ListView and its adapter
List<Message> messages = new ArrayList<>();
mMessageAdapter = new MessageAdapter(this, R.layout.item_message, messages);
mMessageListView.setAdapter(mMessageAdapter);
// Initialize progress bar
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
// ImagePickerButton shows an image picker to upload a image for a message
mPhotoPickerButton.setOnClickListener(new View.OnClickListener() {
// TODO: Fire an intent to show an image picker
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);
}
});
// Enable Send button when there's text to send
mMessageEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(DEFAULT_MSG_LENGTH_LIMIT)});
// Send button sends a message and clears the EditText
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO: Send messages on click
Message message = new Message(mMessageEditText.getText().toString(), mUsername, null);
mMessagesReference.push().setValue(message);
mMessageEditText.setText("");
}
});
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
String userId = user.getUid();
Log.d("onAuthStateChanged: ",userId);
if (user != null) {
} else {
}
}
};
}
#Override
protected void onPause() {
super.onPause();
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
detachDatabaseReadListener();
mMessageAdapter.clear();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
Toast.makeText(this, "Signed in.", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Sign in canceled.", Toast.LENGTH_SHORT).show();
finish();
}
} else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
StorageReference photoRef =
mChatPhotosStorageRef.child(selectedImageUri.getLastPathSegment());
photoRef.putFile(selectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
Message message = new Message(null, mUsername, downloadUrl.toString());
mMessagesReference.push().setValue(message);
}
});
}
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
private void attachDatabaseReadListener() {
if (mChildEventListener == null) {
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Message message = dataSnapshot.getValue(Message.class);
mMessageAdapter.add(message);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
mMessagesReference.addChildEventListener(mChildEventListener);
}
}
private void detachDatabaseReadListener() {
if (mChildEventListener != null) {
mMessagesReference.removeEventListener(mChildEventListener);
mChildEventListener = null;
}
}
}
Is it a 500 error from the server? You better stringyfy the json body,
body: Json.stringify(**content**);

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