2017-02-11 32 views
3

Ich schreibe eine App zum Testen von Firebase, wo ein Benutzer ein Produkt mit Bildern auflisten kann. Ich habe Probleme mit dem Upload, obwohl die Bilder gespeichert sind, sie sind nicht mit dem Produkt verknüpft (Bilder-Array wird nicht übergeben?) Und LeakCanary signalisiert einen Outofmemory-Fehler. Alle Hilfe und Eingabe geschätzt.Android Firebase mehrere Bild hochladen

Hier ist mein Produkt-Modell

@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; 
    } 
} 

Und hier sind meine AddProductActivity ist

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

Was meinen Sie mit "sie sind nicht mit dem Produkt verbunden"? –

+0

Die einzigen Werte sind (UID, Verkäufer, Name, Beschreibung, Stadt und Preis), es ist so, als würde ich das Bilder-Array nicht passieren – Ender

Antwort

1

Der Versuch, Ihren Code Fluss zu verstehen, kann ich eine Sache sehen:

in Ihrem publishProduct Methode sollte den Code (um die Kinder in Firebase aktualisieren) in die addOnSuccessListener, wie folgt:

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); 
        } 
       }); 
    } 

} 

Und wenn Sie, wenn der updateChildren Betrieb wissen wollen, abgeschlossen ist oder nicht, fügen Sie die onComplete und onFailure Zuhörer, wie folgt aus:

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

      } 
}); 

aktualisieren

Ich denke, man kann Versuchen Sie, Ihre Datenbankstruktur zu ändern, indem Sie die Liste der Bilder von den Knoten des Produkts entfernen und stattdessen einen Knoten in Ihrer Datenbank hinzufügen, der nur die Liste der mit jedem Produkt verknüpften Bilder speichert:

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

enthält die Liste seiner Bilder. imageKey unterscheidet sich von einem Bild zum anderen (es könnte beispielsweise der Bildname sein). yourKey könnte die userId oder der Schlüssel mit jedem Produkt verbunden sein, es hängt davon ab, wie die Datenbank strukturiert ist. Dann können Sie versuchen, setValue zu verwenden, anstatt updateChildren in Ihr OnSuccessListener, etwa so:

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()); 

         } 
       }); 

hoffe, das hilft!

Verwandte Themen