0

I have an Android application, which has user authorization via Google+(or Gmail) and I want for each new user to save its Google+ avatar to Firebase Storage in order to use its somewhere in the app.

I can get the Uri of the avatar from GoogleSignInAccount by calling personPhoto = account.getPhotoUrl();.

After, I want to upload the avatar to Firebase Storage, so I can save a link to that avatar in my Firebase Database for users(one of the fields in this database will hold users' avatar).

I've been reading this guide on how to upload file to Firebase Storage. I've realized that users' avatar does not exist on the phone "for real", but I only have its Uri somewhere in my code.

One possible solution is to download the avatar to some folder on phone, and then use the guide I mentioned above.

However, I don't know how to download, and I think it is not the best solution to this problem.

What are the options here?

Here is the code of my onStart method in MainActivity, which does not work, since the avatar is not downloaded on phone.

protected void onStart() {
        super.onStart();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        databaseUsers = FirebaseDatabase.getInstance().getReference("users");
        if (account == null) {
            username.setText("Need to sign in");
            email.setText("");
            avatar.setImageResource(android.R.color.transparent);
        }
        else {
            personName = account.getDisplayName();
            personGivenName = account.getGivenName();
            personFamilyName = account.getFamilyName();
            personEmail = account.getEmail();
            personId = account.getId();
            personPhoto = account.getPhotoUrl();
            username.setText(account.getDisplayName());
            email.setText(account.getEmail());
            final String cleanEmail = email.getText().toString().replaceAll("\\.", ",");

            databaseUsers.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                        if (!snapshot.child(cleanEmail).exists()) {
                            mProgress.setMessage("LUL");
                            mProgress.show();
                            mStorage = FirebaseStorage.getInstance().getReference();


                            InputStream stream = null;
                            try {
                                stream = new FileInputStream("some path here");
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            }

                            StorageReference filePath = mStorage.child("Avatar").child(personPhoto.getPath());
                            UploadTask uploadTask = filePath.putStream(stream);
                            uploadTask.addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception exception) {
                                    // Handle unsuccessful uploads
                                }
                            }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                @Override
                                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                    Uri downloadUrl = taskSnapshot.getDownloadUrl();
                                    mProgress.dismiss();
                                }
                            });
                    }
                }
                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
            if(account.getPhotoUrl() != null){
                Picasso.with(this).load(account.getPhotoUrl()).into(avatar);
            }
            else {
                avatar.setImageResource(R.drawable.userdefault);
            }
        }
    }
False Promise
  • 478
  • 3
  • 6
  • 13

2 Answers2

0

You could store the download URL and then save it to the database under the user/account, etc. In this example I use react-native. I save the download url's to an array then store the array to the database.

export const userVehiclePhotoUploadRequest = (photos, user, year) => dispatch => {
    console.log('Inside vehiclePhotoUpload Actions', photos, user)

    let referenceToUploadedPhotos = [];

    return new Promise((resolve, reject) => {
        photos.map(ele => {
            let mime = 'application/octet-stream'

            let uri = ele.uri
            let uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri
            let sessionId = new Date().getTime()
            let uploadBlob = null
            let imageRef = firebase.storage().ref('vehicleImages/' + `${user.account.uid}`).child(`${sessionId}`)

            fs.readFile(uploadUri, 'base64')
                .then((data) => {
                    return Blob.build(data, { type: `${mime};BASE64` })
                })
                .then((blob) => {
                    uploadBlob = blob
                    return imageRef.put(blob, { contentType: mime })
                })
                .then(() => {
                    uploadBlob.close()
                    return imageRef.getDownloadURL()
                })
                .then((url) => {
                    referenceToUploadedPhotos.push(url)
                    console.log('ARRAY OF URLS WHILE PUSHING', referenceToUploadedPhotos)
                    resolve(url)
                })
                .catch((error) => {
                    reject(error)
                })
        })
    })
        .then(() => {
            //I did this to not go home until photos are done uploading. 

            let vehicles;
            firebase.database().ref('users/' + user.account.uid + `/allVehicles/allVehiclesArray`).limitToFirst(1).once('value').then(function (snapshot) {
                // ******** This method is straight from their docs ********
                // ******** It returns whatever is found at the path xxxxx/users/user.uid ********
                vehicles = snapshot.val();
            }).then(() => {
                console.log('ARRAY OF URLS BEFORE SETTING', referenceToUploadedPhotos)
                // let lastVehicle = vehicles.length - 1;
                firebase.database().ref('users/' + user.account.uid + `/allVehicles/allVehiclesArray/` + `${Object.keys(vehicles)[0]}` + `/photosReference`).set({
                    referenceToUploadedPhotos
                }).then(() => {
                    dispatch(loginRequest(user.account))
                })
            })


        })


};
Gavin Thomas
  • 1,827
  • 2
  • 11
  • 17
0

if you have a photo ,the efficient way is to upload the photo to the server and get its URL and save it to database, In your case it's already in the server (Google's server) why would you want to upload it again while you can use it while it exists in (Google's server),

Save the URL of the image that you obtained from Google on you database and when you need the image just go get the URL the execute that URL

However, if you want to upload the image it-self to the Firebase here how you get it

public Bitmap getBitmapFromURL(String src) {
    try {
        java.net.URL url = new java.net.URL(src);
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

and to upload the Bitmap to Firebase check this

Mohamed Embaby
  • 960
  • 8
  • 26
  • The problem is I don't have a photo. Either you misread my question or I don't understand what a `Uri` is (which seems quite likely). – False Promise Jan 01 '18 at 19:01
  • URL is the destination of the image on the server like https://www.facebook.com/images/fb_icon_325x325.png this image is on the facebook server so I can call it whenever I want as long as I have the URL. why would i download it from facebook server and upload it again to firebase server while i can use it while it is in facebook server . Also, firebase has limit storage for uploading then you have to buy more – Mohamed Embaby Jan 01 '18 at 19:36