2017-02-11 23 views
3

私はユーザーが画像付きの製品をリストできるfirebaseをテストするためのアプリを書いています。 写真が保存されているにもかかわらず、製品にリンクされていない(画像配列が渡されていません)と、LeakCanaryがアウトメモリエラーを起こしたように、アップロードに問題があります。 すべてのヘルプと入力が感謝しています。ここでAndroidファイアベース複数画像アップロード

は私の製品モデル

@IgnoreExtraProperties 
public class Product { 

    public String uid; 
    public String seller; 
    public String name; 
    public String description; 
    public String city; 
    public double price = 0.0; 
    public List<Uri> images = new ArrayList<>(); 

    public Product() { 

    } 

    public Product(String uid, String seller, String name, String description, String city, double price, List<Uri> images) { 
     this.uid = uid; 
     this.seller = seller; 
     this.name = name; 
     this.description = description; 
     this.city = city; 
     this.price = price; 
     this.images = images; 
    } 

    // [START post_to_map] 
    @Exclude 
    public Map<String, Object> toMap() { 
     HashMap<String, Object> result = new HashMap<>(); 
     result.put("uid", uid); 
     result.put("seller", seller); 
     result.put("name", name); 
     result.put("description", description); 
     result.put("city", city); 
     result.put("price", price); 
     result.put("images", images); 

     return result; 
    } 
} 

だし、ここにいるあなたのコードの流れを理解しようとする私のAddProductActivity

public class AddProductActivity extends BaseActivity implements AddProductContract.View, View.OnClickListener { 

    private AddProductContract.Presenter mPresenter; 

    private Bitmap mBitmap; 
    private byte[] mByteArray; 
    private List<String> mPhotos; 
    private Button mPublishBtn; 
    private EditText mProductNameField; 
    private EditText mProductDescriptionField; 
    private EditText mProductPriceField; 
    private DatabaseReference mFirebaseDatabase; 
    private StorageReference mFirebaseStorage; 
    private StorageTask mUploadTask; 
    private List<Uri> uploadedImages = new ArrayList<>(); 
    private LinearLayout mLinearLayout; 
    private ImageButton mImageButton; 

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

     if (data == null) { 
      showEmptyImageError(); 
     } else { 
      mPhotos = (List<String>) data.getSerializableExtra(GalleryActivity.PHOTOS); 
     } 

    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_add_edit_product_2); 

     mFirebaseDatabase = FirebaseDatabase.getInstance().getReference(); 
     mFirebaseStorage = FirebaseStorage.getInstance().getReference(); 

     Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(mToolbar); 
     getSupportActionBar().setDisplayShowTitleEnabled(false); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setDisplayShowHomeEnabled(true); 

     mToolbar.setTitle(R.string.addItemTextview); 

     mLinearLayout = (LinearLayout) findViewById(R.id.activity_add_product); 
     mLinearLayout.setOnClickListener(this); 

     mImageButton = (ImageButton) findViewById(R.id.imageButton); 
     mImageButton.setOnClickListener(this); 

     mPublishBtn = (Button) findViewById(R.id.publishItemBtn); 
     mPublishBtn.setOnClickListener(this); 

     mProductNameField = (EditText) findViewById(R.id.productNameField); 
     mProductDescriptionField = (EditText) findViewById(R.id.productDescriptionField); 
     mProductPriceField = (EditText) findViewById(R.id.priceField); 

     // mPresenter = new AddProductPresenter(this); 
    } 

    @Override 
    public void onClick(View view) { 
     if ((view == mLinearLayout)) { 
      hideKeyboard(); 
     } else if (view == mImageButton) { 
      GalleryConfig config = new GalleryConfig.Build() 
        .limitPickPhoto(8) 
        .singlePhoto(false) 
        .hintOfPick("You can pick up to 8 pictures.") 
        .filterMimeTypes(new String[]{"image/*"}) 
        .build(); 
      GalleryActivity.openActivity(AddProductActivity.this, 2, config); 
     } else if (view == mPublishBtn) { 
      final String name = mProductNameField.getText().toString(); 
      final String description = mProductDescriptionField.getText().toString(); 
      final double price = Double.parseDouble(mProductPriceField.getText().toString()); 
      setPublishingEnabled(false); 
      showErrorToast(getResources().getString(R.string.publishing)); 
      final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid(); 
      mFirebaseDatabase.child("users").child(userId).addListenerForSingleValueEvent(
        new ValueEventListener() { 
         @Override 
         public void onDataChange(DataSnapshot dataSnapshot) { 
          User user = dataSnapshot.getValue(User.class); 
          if (user == null) { 
           showErrorToast(getResources().getString(R.string.empty_user)); 
          } else { 
           publishProduct(userId, user.getUsername(), name, description, 
             user.getCity(), price, mPhotos); 
          } 
          setPublishingEnabled(true); 
          finish(); 
         } 

         @Override 
         public void onCancelled(DatabaseError databaseError) { 
          Log.w("AddProductActivity", "getUser:onCancelled", databaseError.toException()); 
          setPublishingEnabled(true); 
         } 
        } 
      ); 
     } 
    } 


    private void setPublishingEnabled(boolean enabled) { 
     if (enabled) { 
      mPublishBtn.setVisibility(View.VISIBLE); 
     } else { 
      mPublishBtn.setVisibility(View.GONE); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // handle arrow click here 
     if (item.getItemId() == android.R.id.home) { 
      finish(); 
     } 

     return super.onOptionsItemSelected(item); 
    } 


    @Override 
    public void showEmptyImageError() { 
     Toast.makeText(getApplicationContext(), R.string.empty_image_error, Toast.LENGTH_SHORT).show(); 
    } 

    private void publishProduct(String userId, String seller, String name, String description, 
           String city, double price, List<String> images) { 

     for (String photo : images) { 
      Uri file = Uri.fromFile(new File(photo)); 
      StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment()); 
      mUploadTask = photoRef.putFile(file); 

      mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check")) 
        .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { 
         @Override 
         public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { 
          Uri downloadUrl = taskSnapshot.getDownloadUrl(); 
          uploadedImages.add(downloadUrl); 
         } 
        }); 
     } 


     String key = mFirebaseDatabase.child("products").push().getKey(); 
     Product product = new Product(userId, seller, name, description, city, price, uploadedImages); 
     Map<String, Object> productValues = product.toMap(); 

     Map<String, Object> childUpdates = new HashMap<>(); 
     childUpdates.put("/products/" + key, productValues); 
     childUpdates.put("/user-products/" + userId + "/" + key, productValues); 

     mFirebaseDatabase.updateChildren(childUpdates); 
    } 

// 
// private List<Uri> uploadPhotos(List<String> input) { 
//  images = new ArrayList<>(); 
//  Observable.just(input) 
//    .map(this::doInBackground) 
//    .subscribeOn(Schedulers.io()) 
//    .observeOn(AndroidSchedulers.mainThread()) 
//    .doOnSubscribe(this::onPreExecute) 
//    .subscribe(this::onPostExecute); 
//  return images; 
// } 
// 
// private void onPreExecute() { 
//  Log.i("Start time", "SET"); 
//  Toast.makeText(this, R.string.image_formatting_toast, Toast.LENGTH_SHORT).show(); 
// } 
// 
// private List<Uri> doInBackground(List<String> photos) { 
//  for (String photo : mPhotos) { 
//   Uri file = Uri.fromFile(new File(photo)); 
//   StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment()); 
//   mUploadTask = photoRef.putFile(file); 
// 
//   mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check")) 
//     .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { 
//    @Override 
//    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { 
//     Uri downloadUrl = taskSnapshot.getDownloadUrl(); 
//     images.add(downloadUrl); 
//    } 
//   }); 
//  } 
//  return images; 
// } 
// 
// private void onPostExecute(List<Uri> uriSet) { 
//  Toast.makeText(this, R.string.product_visibility_toast, Toast.LENGTH_SHORT).show(); 
//  Log.i("End time", "SET"); 
// } 

} 
+0

「商品にリンクされていません」とはどういう意味ですか? –

+0

唯一の値は(uid、売り手、名前、説明、都市、価格)ですが、私は画像配列を渡していないようです – Ender

答えて

1

ですが、私は一つのこと見ることができます:あなたのpublishProduct方法あなたの中

を次のようにaddOnSuccessListenerにコードを置くべきです(Firebaseのchilderenを更新する)。

private void publishProduct(String userId, String seller, String name, String description, 
          String city, double price, List<String> images) { 

    String key = mFirebaseDatabase.child("products").push().getKey(); 

    for (String photo : images) { 
     Uri file = Uri.fromFile(new File(photo)); 
     StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment()); 
     mUploadTask = photoRef.putFile(file); 

     mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check")) 
       .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { 
        @Override 
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { 
         Uri downloadUrl = taskSnapshot.getDownloadUrl(); 
         uploadedImages.add(downloadUrl); 

         Product product = new Product(userId, seller, name, description, city, price, uploadedImages); 
         Map<String, Object> productValues = product.toMap(); 

         Map<String, Object> childUpdates = new HashMap<>(); 
         childUpdates.put("/products/" + key, productValues); 
         childUpdates.put("/user-products/" + userId + "/" + key, productValues); 

         mFirebaseDatabase.updateChildren(childUpdates); 
        } 
       }); 
    } 

} 

そして、あなたはupdateChildren操作が完了したかどうかを知るか、onCompleteのとONFAILUREリスナーを追加し、このようにしたい場合:

mFirebaseDatabase.updateChildren(childUpdates).addOnCompleteListener(new OnCompleteListener<Void>() { 
      @Override 
      public void onComplete(@NonNull Task<Void> task) { 

      }).addOnFailureListener(new OnFailureListener() { 
      @Override 
      public void onFailure(@NonNull Exception e) { 

      } 
}); 

更新

私はあなたができると思いますデータベースの構造を変更して、製品のノードからイメージのリストを削除し、代わりに各製品に関連付けられたイメージのリストのみを格納するノードをデータベースに追加します。

"/product-images/" + yourKey + "/" + imageKey 

には、彼の画像のリストが含まれています。 imageKeyは、別のイメージと異なります(イメージ名など)。 yourKeyuserIdであるか、各製品に関連付けられたキーである可能性があります。これは、データベースの構造によって異なります。その後、あなたはOnSuccessListenersetValueの代わりupdateChildrenを使用しようとすることができ、このような何か:

mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check")) 
        .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { 
         @Override 
         public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { 
          Uri downloadUrl = taskSnapshot.getDownloadUrl();    

          mFirebaseDatabase.child("product-images").child(yourKey).child(imageKey).setValue(downloadUrl.toString()); 

         } 
       }); 

は、この情報がお役に立てば幸い!

関連する問題