从firebase

时间:2017-11-29 14:14:58

标签: java android firebase firebase-realtime-database

我遇到从数据库中检索数据的问题。 当我打开应用程序时,应用程序将从onCreate()中的firebase获取数据并将其添加到回收站视图中。 数据的结构如下:

"Items" {
    "some category" {
         "useruid" {
             "some key" {
                  "Title" : "Some time",
                  "Info" : "Some info about the item",
                  "photoitem" : "A image that is compressed / encoded to a base 64 string"
                  "useruid" : "the user uid, which i use for something else" 
            }
        }
    }
}

现在,在我测试的时候,我有3个项目(“一些键”)。当我检索数据时,我可以在Android Profiler中看到该应用程序使用16mb的数据来检索这三个项目,这太过分了。应用程序在检索图像时是否使用了这么多数据,或者我做错了什么?

注意:数据库中的结构使得从不同类别获取项目变得容易,并且仅显示用户具有/不具有的项目。

任何提示/帮助都会非常有帮助。从26.11开始直到今天,我的应用程序仅通过测试(打开应用程序,然后关闭等)使用了9,4gb的数据。

这就是我将图像保存到firebase的方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    //Dersom startActivityForResult er velykket, kjøres denne
    Log.d(TAG, " Før requestCode check");
    if (requestCode == REQUEST_IMAGE_CAPTURE) {
        Log.d(TAG, " Før resultCode check");
        if (resultCode == RESULT_OK) {
            //Setter bildet i imageviewet og sender det til firebasedatabasen
            //setPic();
            //Lagrer bildet i galleriet
            galleryAddPic();

            Log.d(TAG, " Bilde lagt til i galleri");

            try {
                handleSamplingAndRotationBitmap(getApplicationContext(), photoURI);
            }
            catch (IOException e) {Log.d(TAG, "Fungerte ikke");}
        }
    }

}

    //Gjør om bildet til base64 (en String), slik at det kan legges til i databasen som en string

    public void addImageToFirebase(Bitmap bitmap) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        imageEncoded = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
        Log.d(TAG, "Image added to firebase");
        try {
            baos.close();
        }
        catch (IOException e) {
            Log.d(TAG, e.getMessage());

        }


    }

    public void handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
            throws IOException {
        int MAX_HEIGHT = 1024;
        int MAX_WIDTH = 1024;

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
        BitmapFactory.decodeStream(imageStream, null, options);
        imageStream.close();

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        imageStream = context.getContentResolver().openInputStream(selectedImage);
        Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

        img = rotateImageIfRequired(context, img, selectedImage);

        //Legger bildet til i databasen
        //Legger bildet til i imageviewet
        ImageView imageview = (ImageView) findViewById(R.id.userImageInput);
        imageview.setImageBitmap(img);
        addImageToFirebase(img);

    }

    private static int calculateInSampleSize(BitmapFactory.Options options,
                                         int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 2;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
            // with both dimensions larger than or equal to the requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

            final float totalPixels = width * height;

            // Anything more than 2x the requested pixels we'll sample down further
            final float totalReqPixelsCap = reqWidth * reqHeight * 2;

            while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                inSampleSize++;
            }
        }
        return inSampleSize;
    }

    private static Bitmap rotateImageIfRequired(Context context, Bitmap img, Uri selectedImage) throws IOException {

    InputStream input = context.getContentResolver().openInputStream(selectedImage);
    ExifInterface ei;
    if (Build.VERSION.SDK_INT > 23)
        ei = new ExifInterface(input);
    else
        ei = new ExifInterface(selectedImage.getPath());

    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotateImage(img, 90);
        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotateImage(img, 180);
        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotateImage(img, 270);
        default:
            return img;
    }
}

这就是图像字符串被解码的方式:

//Retrieving from firebase:
private void prepareItemData() {
    database = FirebaseDatabase.getInstance();
    DatabaseReference dbref = database.getReference("Items");

    dbref.child("category").addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            if(dataSnapshot.exists()) {
                for(DataSnapshot ds: dataSnapshot.getChildren()) {
                    if(!dataSnapshot.getKey().equals(thisUser)) {
                        Items item1 = ds.getValue(Items.class);
                        lowagedata.add(item1);
                    }
                }
                iAdapter.notifyDataSetChanged();
            }

        }

        @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) {

        }
    });
}

//Here is the decoder: 

public static Bitmap decodeFromFirebaseBase64(String image) throws IOException {
    byte[] decodedByteArray = android.util.Base64.decode(image, Base64.DEFAULT);
    return BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedByteArray.length);
}

1 个答案:

答案 0 :(得分:0)

不要将图像存储在Firebase数据库中。绝对没有理由这样做,而这仅仅会增加你的内存使用量(由于数据在内存中并需要base64编码)。

而是将图像存储在Cloud Storage for Firebase中。这样做的好处是,您可以upload them straight from the device diskdownload them straight to the device disk,并且您不需要对数据进行base64编码。

另请参阅以下问题:Firebase在哪里存储哪种类型的数据: