ʻWhen using Firebase Storage on Android`, it is natural to upload multiple files at once. However, no such API is currently available. I was in trouble ... So I decided to upload multiple files to Zip at once.
SimpleFirebaseStorageDatabase.java
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class SimpleFirebaseStorageDatabase {
    private static final String TAG = "SimpleFirebaseStorageDB";
    private String userId;
    private StorageReference storageRef;
    private DatabaseReference databaseRef;
    private Context mContext;
    private static final long MAX_DOWNLOAD_SIZE = 1024 * 1024 * 5;
    public SimpleFirebaseStorageDatabase (Context context, FirebaseAuth mAuth, String firebaseStorageBucketToken) {
        mContext = context;
        FirebaseUser user = mAuth.getCurrentUser();
        if (user == null) {
            return;
        }
        this.userId =  user.getUid();
        storageRef = FirebaseStorage.getInstance().getReferenceFromUrl(firebaseStorageBucketToken).child("users").child(userId);
    }
    public void uploadFilesByTempFile (final String projectName, List<String> uris) {
        File zip = zipFilesToFile(projectName, uris);
        if (zip == null) {
            Log.e(TAG, "No zip file is created: " + projectName);
            return;
        }
        try {
            storageRef.child(projectName).putFile(Uri.fromFile(zip)).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess (UploadTask.TaskSnapshot taskSnapshot) {
                    Log.d(TAG, "Succeeded to upload project : " + projectName);
                    storageRef.child(projectName).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess (Uri uri) {
                            Log.d(TAG, "Succeeded to get download url : " + uri);
                            onUploadSuccess(uri.toString());
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure (@NonNull Exception e) {
                            Log.e(TAG, "Failed to get download url : " + projectName, e);
                            onUploadFail();
                        }
                    });
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure (@NonNull Exception e) {
                    Log.e(TAG, "Failed to upload project : " + projectName, e);
                    onUploadFail();
                }
            });
        } catch (Exception e) {
            onUploadFail();
        }
    }
    private File zipFilesToFile(String projectName, List<String> uris) {
        try {
            File projFile = new File(mContext.getFilesDir(), projectName);
            Log.d(TAG, "Make project zip file: " + projFile.getPath());
            //Suppose the output destination file path is specified in String outfilePath
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(projFile));
            byte[] buffer = new byte[1024 * 4];
            int len = 0;
            //String with arguments etc.[]Suppose the file path of the file you want to add to the zip is specified as files
            for (String uri : uris) {
                zipOneFile(uri, out, buffer);
            }
            out.close();
            Log.d(TAG, "Succeeded to make project zip file: " + projFile.getPath());
            return projFile;
        } catch(Exception e){
            //Error handling
            Log.e(TAG, "Failed to make project zip file: " + projectName, e);
        }
        return null;
    }
    /**
     *Add one file of the specified Uri to ZIP.
     * @param uri path to the file to compress(Uri)
     * @param os
     * @param buffer
     */
    private static void zipOneFile(String uri, ZipOutputStream os, byte[] buffer) {
        InputStream in = null;
        int len = 0;
        try {
            Log.d(TAG, "Zip one file : " + uri);
            String path = Uri.parse(uri).getPath();
            File inFile = new File(path);
            if (!inFile.exists()) {
                Log.w(TAG, "File doesn't exist: " + uri);
                return;
            }
            in = new FileInputStream(inFile);
            os.putNextEntry(new ZipEntry(inFile.getName())); //Keep only the file name from the path name
            while ((len = in.read(buffer)) > 0) {
                os.write(buffer, 0, len);
            }
        } catch (Exception e) {
            Log.e(TAG, "Failed to zip file: " + uri, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                    // do nothing
                }
            }
        }
    }
    private void onUploadSuccess (String downloadUri) {
        if (mContext instanceof OnFirebaseStorageUploadListener) {
            ((OnFirebaseStorageUploadListener) mContext).onUploadSucceed(downloadUri);
        }
    }
    private void onUploadFail () {
        if (mContext instanceof OnFirebaseStorageUploadListener) {
            ((OnFirebaseStorageUploadListener) mContext).onUploadFailed();
        }
    }
    public interface OnFirebaseStorageUploadListener {
        void onUploadSucceed (String downloadUri);
        void onUploadFailed ();
    }
MainActivity.java
public class MainActivity extends AppCompatActivity implements SimpleFirebaseStorageDatabase.OnFirebaseStorageUploadListener{
    private List<String> mUriList;
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SimpleFirebaseStorageDatabase firebaseStorage = new SimpleFirebaseStorageDatabase(ShareProjectActivity.this, mAuth, "Bucket token");
        mUriList = // ...
        firebaseStorage.uploadFilesByTempFile("file name.zip", mUriList);
    }
    @Override
    public void onUploadSucceed (String downloadUri) {
        //success
    }
    @Override
    public void onUploadFailed () {
        //Failure
    }
There is no explanation this time. I will write about the corresponding download process later. For the login process required when using Firebase, click here [https://qiita.com/Cyber_Hacnosuke/items/0c291e240034872eba65) Twitter (Please follow me.): Https://twitter.com/Cyber_Hacnosuke
Recommended Posts