2017-01-04 12 views
0

完全なデバッグの後、OnSuccessListenersgetData()getImage()の両方にあるため、Firebox Storageのサムネイルとタイトルを取得してから私のGridViewに画像が表示されないと結論づけました。まだ成功していない。Firebase Storage OnSuccessListenersが時間内に成功していない

私はgetData()の方法でこれを行います。これはユーザーがonActivityResultにGoogleプレイスを選択した後に呼びます。このメソッドは新しいImageItem(ビットマップ、ストリング)をインスタンス化する必要がありますが、がまだ成功していないため、null ImageItemを返しています。何か案は?

private void getData() { 
     imageItems = new ArrayList<>(); 
     DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference(); 
     mDatabase.child((String) p.getName()).addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator(); 
       FirebaseStorage storage = FirebaseStorage.getInstance(); 
       StorageReference httpsReference = storage.getReferenceFromUrl(myUrl); 
       while (iter.hasNext()) { 
        hasImage = false; 
        hasTitle = false; 
        HashMap<String, String> m = (HashMap<String, String>) iter.next().getValue(); 
        String v = m.get("url"); 
        Log.d("url", v); 

        String bu = m.get("bucket"); 
        Log.d("bucket", bu); 
        b = getImage(bu, v); 
        StorageReference iR = httpsReference.child(bu).child("thumb"); 

        httpsReference.child(bu).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() { 
         @Override 
         public void onSuccess(StorageMetadata storageMetadata) { 
          // Metadata now contains the metadata for 'images/forest.jpg' 
          t = storageMetadata.getCustomMetadata("title"); 
          hasTitle = true; 
          Log.d("title", t); 
         } 
        }).addOnFailureListener(new OnFailureListener() { 
         @Override 
         public void onFailure(@NonNull Exception exception) { 
          Log.d("error", "ERROr"); 
          // Uh-oh, an error occurred! 
         } 
        }); 


        gridAdapter.data.add(new ImageItem(b, t, bu, v)); 


       } 

      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 


    } 



public Bitmap getImage(String bx, String vu) { 
    FirebaseStorage storage = FirebaseStorage.getInstance(); 
    StorageReference httpsReference = storage.getReferenceFromUrl(myUrl); 


    String v = vu; 
    Log.d("url", v); 

    String bu = bx; 
    Log.d("bucket", bu); 
    StorageReference iR = httpsReference.child(bu).child("thumb"); 

    final long ONE_MEGABYTE = 1024 * 1024; 
    iR.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() { 
     @Override 
     public void onSuccess(byte[] bytes) { 
      // Data for "images/island.jpg" is returns, use this as needed 
      b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 

      hasImage = true; 
     } 
    }).addOnFailureListener(new OnFailureListener() { 
     @Override 
     public void onFailure(@NonNull Exception exception) { 
      // Handle any errors 
     } 
    }); 
    return b; 
} 
} 

**************** UPDATE 2017年1月7日*********************

private void getData() { 
     imageItems = new ArrayList<>(); 
     DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference(); 
     mDatabase.child((String) p.getName()).addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator(); 
       FirebaseStorage storage = FirebaseStorage.getInstance(); 
       final StorageReference httpsReference = storage.getReferenceFromUrl("gs://socialnetwork-4b0c9.appspot.com"); 
       while (iter.hasNext()) { 
        hasImage = false; 
        hasTitle = false; 
        HashMap<String, String> m = (HashMap<String, String>) iter.next().getValue(); 
        final String v = m.get("url"); 
        Log.d("url", v); 

        final String bu = m.get("bucket"); 
        Log.d("bucket", bu); 
        StorageReference iR = httpsReference.child(bu).child("thumb"); 
        final long ONE_MEGABYTE = 1024 * 1024; 
        iR.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() { 
         @Override 
         public void onSuccess(byte[] bytes) { 
          // Data for "images/island.jpg" is returns, use this as needed 
          b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 

          httpsReference.child(bu).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() { 
           @Override 
           public void onSuccess(StorageMetadata storageMetadata) { 
            // Metadata now contains the metadata for 'images/forest.jpg' 
            t = storageMetadata.getCustomMetadata("title"); 
            hasTitle = true; 
            gridAdapter.data.add(new ImageItem(b, t, bu, v)); 
            Log.d("title", t); 
           } 
          }).addOnFailureListener(new OnFailureListener() { 
           @Override 
           public void onFailure(@NonNull Exception exception) { 
            Log.d("error", "ERROr"); 
            // Uh-oh, an error occurred! 
           } 
          }); 
         } 
        }).addOnFailureListener(new OnFailureListener() { 
         @Override 
         public void onFailure(@NonNull Exception exception) { 
          // Handle any errors 
         } 
        }); 


       } 

      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 


    } 

************************のGridViewとGRIDADAPTERに関するMETHOD *********

@Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) { 
      if (resultCode == RESULT_OK) { 
       Place place = PlaceAutocomplete.getPlace(this, data); 
       p = place; 

       gridView = (GridView) findViewById(R.id.grid_View); 

       gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout); 
       getData(); 
       gridView.setAdapter(gridAdapter); 

       gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
         ImageItem item = (ImageItem) parent.getItemAtPosition(position); 
         //Create intent 
         Intent intent = new Intent(PlaceActivity.this, VideoActivity.class); 
         intent.putExtra("bucket", item.getBucket()); 
         intent.putExtra("dUrl", item.getdUrl()); 


         //Start details activity 
         startActivity(intent); 
        } 
       }); 


      } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) { 
       Status status = PlaceAutocomplete.getStatus(this, data); 
       // TODO: Handle the error. 


      } else if (resultCode == RESULT_CANCELED) { 
       // The user canceled the operation. 
      } 
     } 
    } 
+0

使用しているFirebaseストレージのどのバージョン:

var a = 1; incrementAsync(function() { a = 2; console.log(a); // prints 2 now }); 

は、だから私は、あなたの関数を再書き込みしたいですか?エラーはありますか?あなたはアプリケーションの特定のロジックなしで、この動作の短い例を投稿していただけますか? SOCコードで500 LoCを読むのは難しいです。より良い例を構築するための詳細については、http://stackoverflow.com/help/mcveを参照してください。 –

+0

また、すべてのデータを手動で解析する 'SingleEventListener' +の代わりに' ChildEventListener'を使用してください。 Firebase DBは、あなたがそれを手伝ってくれるなら、あなたのために大いに役立ちます:) https://firebase.google.com/docs/database/android/lists-of-data –

+0

ちょっとマイク、あなたの応答に感謝します。私は私の問題peratinsに2つの方法だけを表示するように私の質問を編集しました。 – androidcoder1234

答えて

0

これは古典的な非同期プログラミングの問題です:

var a = 1; 

incrementAsync(function() { 
    a = 2; 
}); 

console.log(a); // prints 1 because the function hasn't returned yet 
あなたが代わりに非同期機能でアクションを実行する必要があり

FirebaseDatabase mDatabase = FirebaseDatabase.getInstance(); 
FirebaseStorage mStorage = FirebaseStorage.getInstance(); 

mDatabase.getReference("...").addChildEventListener(new ChildEventListener() { 
    @Override 
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { 
     ModelObject modelObject = storage.getValue(ModelObject.class); 
     // Or just download the object here... 
     mStorage.getReferenceFromUrl(modelObject.getUrl()).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() { 
      @Override 
      public void onSuccess(StorageMetadata storageMetadata) { 
       String title = storageMetadata.getCustomMetadata("title"); 
       gridAdapter.data.add(...); 
      } 
     }).addOnFailureListener(new OnFailureListener() { 
      @Override 
      public void onFailure(@NonNull Exception exception) { 
       // Uh-oh, an error occurred! 
      } 
     }); 
    } 
    ... 
}); 
+0

上記の実装を追加しました。サムネイルとタイトルがログに基づいて正常にダウンロードされていると思います。私はまず画像をダウンロードしてからonSucessでメタデータをダウンロードします。しかし、私のアダプターはサムネイルとそのタイトルをロードしていませんか?ご協力ありがとうございました。私は数週間これに固執しています。 – androidcoder1234

関連する問題