我遇到从数据库中检索数据的问题。
当我打开应用程序时,应用程序将从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);
}
答案 0 :(得分:0)
不要将图像存储在Firebase数据库中。绝对没有理由这样做,而这仅仅会增加你的内存使用量(由于数据在内存中并需要base64编码)。
而是将图像存储在Cloud Storage for Firebase中。这样做的好处是,您可以upload them straight from the device disk,download them straight to the device disk,并且您不需要对数据进行base64编码。
另请参阅以下问题:Firebase在哪里存储哪种类型的数据: