4

I am trying to add an image to the user information in the real time database(firebase) for android. I have uploaded the image on the firebase storage but how will I be able to add the image in the database for that user?

Code Below:

//inside onCreate() method

img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i=new Intent(Intent.ACTION_PICK);
            i.setType("image/*");
            startActivityForResult(i,request_code);
        }
    });

Here I am clicking on the imageview, so I will be able to change it and get an image from the gallery.

Here I authenticate the user and send data to the database:

 auth.createUserWithEmailAndPassword(email, password)
                    .addOnCompleteListener(StudentSignUpActivity.this, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            Toast.makeText(getApplicationContext(), "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
                            progressBar.setVisibility(View.GONE);
                            // If sign in fails, display a message to the user. If sign in succeeds
                            // the auth state listener will be notified and logic to handle the
                            // signed in user can be handled in the listener.
                            if (!task.isSuccessful()) {
                                Toast.makeText(getApplicationContext(), "Authentication failed." + task.getException(),
                                        Toast.LENGTH_SHORT).show();
                            } else {
                                startActivity(new Intent(StudentSignUpActivity.this, HomeActivity.class));
                                finish();
                            }
                        }
                    });

mCurrentUser=FirebaseAuth.getInstance().getCurrentUser();
            DatabaseReference newStudent=mDatabase.push();
            newStudent.child("email").setValue(email);
            newStudent.child("password").setValue(password);
            newStudent.child("name").setValue(name);
            newStudent.child("date").setValue(dates);
            newStudent.child("phone").setValue(number);
            newStudent.child("uid").setValue(mCurrentUser.getUid());


//outside of onCreate()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==request_code&&resultCode==RESULT_OK){
        Uri uri=data.getData();
        StorageReference filepath=mStorage.child("Images").child(uri.getLastPathSegment());
        filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

            }
        });
    }
}

In the above code I have uploaded the image to the firebase storage. Now how will i be able to add that image as a child for a specific user.

I think I need to do something like this:

 newStudent.child("image").setValue(uri_here);

But I am unable to figure how to get the uri of the image and how to add that uri in the setValue() since its in another method.

KENdi
  • 7,576
  • 2
  • 16
  • 31
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134

2 Answers2

3

You can use the method getDownloadUrl() in the success listener to access the download URL:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==request_code&&resultCode==RESULT_OK){
        Uri uri=data.getData();
        StorageReference filepath=mStorage.child("Images").child(uri.getLastPathSegment());
        filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                Uri downloadUrl = taskSnapshot.getDownloadUrl();
                newStudent.child("image").setValue(downloadUrl);
            }
        });
    }
}

As an aside, instead of using push(), I recommend storing the user's data with the uid as the key. This will make your data easier to find.

private DatabaseReference newStudent;

mCurrentUser=FirebaseAuth.getInstance().getCurrentUser();
            newStudent=mDatabase.child(mCurrentUser.getUid());
            newStudent.child("email").setValue(email);
            // etc
Jen Person
  • 7,356
  • 22
  • 30
  • actually the `newStudent=mDatabase.child(mCurrentUser.getUid())` does not work its returning null point exception, since there is no user signed in yet. The code above is for the sign up – Peter Haddad Oct 18 '17 at 05:54
  • You can fetch the image uri from firebase. But the uri comes with the token attached. And you can update that uri to the user profile. But the catch is What if token expires which is attached with the uri? And May be you will get error when you try to fetch user profile url. – AkshayT Apr 07 '18 at 16:23
  • What if the user changes the profile? The url changes so places in database where the previous url was used will show old image. How to overcome that ? – Kartik Watwani Jul 20 '18 at 12:55
3

Just to update because I spent sometime to find this answer, getDownloadUrl() is NOT a function of taskSnapshot anymore. So in order to get the image URL from Firebase Storage you need to add a listener to taskSnapshot.getMetadata().getReference().getDownloadUrl()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==request_code&&resultCode==RESULT_OK){
        Uri uri=data.getData();
        StorageReference filepath=mStorage.child("Images").child(uri.getLastPathSegment());
        filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                taskSnapshot.getMetadata().getReference().getDownloadUrl()
                    .addOnSuccessListener(new OnSuccessListener<Uri>() {

                    @Override
                    public void onSuccess(Uri uri) {
                        newStudent.child("image").setValue(uri);

                    }
                });
            }
        });
    }
}

Now it's safe to use uri to whatever you want

Leonardo Rick
  • 680
  • 1
  • 7
  • 14