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");
Related
my app start with register activity that asks for their phone num, after entering phone numb a otp code would be received then entered to access the final stage of creating an account which is setup profile name and picture.
my problem is if the user closed the app when he is setup profile activity which is after otp,
next time he opens the app he would still be logged in even if the phone and account is not created yet at firebase.
SetProfileActivity:
public class SetupProfileActivity extends AppCompatActivity {
ActivitySetupProfileBinding binding;
FirebaseAuth auth;
FirebaseDatabase database;
FirebaseStorage storage;
Uri selectedImage;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySetupProfileBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
database = FirebaseDatabase.getInstance();
storage = FirebaseStorage.getInstance();
auth = FirebaseAuth.getInstance();
dialog = new ProgressDialog(this);
dialog.setMessage("Uploading Profile Setting...");
dialog.setCancelable(false);
binding.profileImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 45);
}
});
binding.finishBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String name = binding.nameBox.getText().toString();
if (name.isEmpty()) {
binding.nameBox.setError(getString(R.string.cant_be_empty));
return;
}
dialog.show();
if (selectedImage !=null){
StorageReference reference = storage.getReference().child("Profiles").child(auth.getUid());
reference.putFile(selectedImage).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()){
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String imageUrl = uri.toString();
String uid = auth.getUid();
String phone = auth.getCurrentUser().getPhoneNumber();
String name = binding.nameBox.getText().toString().trim();
User user = new User(uid, name, phone, imageUrl);
database.getReference()
.child("Users")
.child(phone)
.setValue(user)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
Intent intent = new Intent(SetupProfileActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
}
});
}
}
});
} else {
String uid = auth.getUid();
String phone = auth.getCurrentUser().getPhoneNumber();
User user = new User(uid, name, phone, "No Image");
database.getReference()
.child("Users")
.child(phone)
.setValue(user)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
Intent intent = new Intent(SetupProfileActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data !=null){
if (data.getData() !=null){
binding.profileImageView.setImageURI(data.getData());
selectedImage = data.getData();
}
}
}
// check if want to exit
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, getString(R.string.click_again_to_Exit), Toast.LENGTH_SHORT).show();
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
}
Since you tagged with firebase-realtime-database I'm going to assume that is where you store the additional profile information.
If so, you will have to:
Try and read the profile information for the current user when the app starts.
If the information exists, redirect them to the main activity.
If the information does not exist, redirect them to the registration page.
I was watching YouTube for the instruction implementing storing image to firebase storage.
But, I got an error with getDownloadUrl() I do not know why, it was given codes from firebase helper.
public class SellerPage extends AppCompatActivity {
EditText Address;
EditText price;
EditText description;
Button register;
Button chooseImage;
private FirebaseAuth auth;
private FirebaseFirestore mFirestore;
private StorageReference mStorageRef;
private static final int RESULT_LOAD_IMAGE = 1;
private static final int IMAGE_PICK_CODE = 1000;
private static final int PERMISSION_CODE = 1001;
ImageView View;
public Uri imgUir;
private StorageTask uploadTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seller_page);
auth = FirebaseAuth.getInstance();
mFirestore= FirebaseFirestore.getInstance();
mStorageRef = FirebaseStorage.getInstance().getReference("Images"); // Storage for the image
Address = (EditText) findViewById(R.id.Address);
price = (EditText) findViewById(R.id.Price);
description = (EditText) findViewById(R.id.description);
register = (Button) findViewById(R.id.addButton);
chooseImage = (Button) findViewById(R.id.image);
View = (ImageView) findViewById(R.id.imageView);
chooseImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check runtime permission
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED){
// permission not granted. then request it
String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE};
requestPermissions(permissions, PERMISSION_CODE);
}else{
//permition already granted
pickImageFromGallay();
}
}else{
// OS is less than marshmello
pickImageFromGallay();
}
}
}
);
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FileUploader();
addSellerInfo();
}
});
}
private void pickImageFromGallay(){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && requestCode == IMAGE_PICK_CODE && data != null){
imgUir = data.getData();
View.setImageURI(data.getData());
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
// super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode){
case PERMISSION_CODE:{
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
pickImageFromGallay();
}else{
Toast.makeText(this,"Permission denied!", Toast.LENGTH_SHORT).show();
}
}
}
}
private String getExtension(Uri uri){
ContentResolver cr = getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(cr.getType(uri));
}
private void FileUploader(){
final StorageReference Ref = mStorageRef.child(System.currentTimeMillis()+ "." + getExtension(imgUir));
Ref.putFile(imgUir)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Get a URL to the uploaded content
//Uri downloadUrl = taskSnapshot.getDownloadUrl();
Toast.makeText(SellerPage.this, "Uploading Image Successful", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
// ...
}
});
}
public void addSellerInfo(){
FirebaseUser user = auth.getCurrentUser();
String ID = user.getUid();
String addressStr = Address.getText().toString().trim();
String priceStr = price.getText().toString().trim();
String descriptionStr = description.getText().toString().trim();
CollectionReference parkspaces = mFirestore.collection("parkspaces");
sellerData parkspace = new sellerData(ID, addressStr, priceStr, descriptionStr);
parkspaces.add(parkspace);
}
}
call getDownloadUrl(), the call is asynchronous and you must subscribe on a success callback to obtain the results:
Ref.putFile(imgUir)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri downloadPhotoUrl) {
Log.e("downloaduri", downloadPhotoUrl.toString());
Toast.makeText(SellerPage.this, "Uploading Image Successful", Toast.LENGTH_LONG).show();
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
// ...
}
});
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);
}
}
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**);
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.