Хранилище Firebase для Android, загрузка внутреннего класса в bitmap

#android #firebase #firebase-realtime-database #firebase-storage #anonymous-inner-class

#Android #firebase #firebase-база данных в реальном времени #firebase-хранилище #анонимный-внутренний класс

Вопрос:

У меня возникли некоторые проблемы со списком Android. У меня есть метод, который создает список игроков и загружает игроков из базы данных firebase и хранилища.

У некоторых игроков есть изображения профиля, и они хранятся как сгенерированный ключ в storage/players/keyname (уникальный ключ игрока в базе данных — это имя профиля в Firebase storage).

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь создать onsucclistener / player. Кажется, я просто не могу передать данные.

Проблемы с Onsucclistener:

  • Все, что находится снаружи, считается «внешним классом», что означает, что когда я хочу создать проигрыватель, он не может прочитать данные внутри onsucclistener.
  • все, что внутри, не может передавать какие-либо данные за пределы прослушивателя.
  • Я не могу преобразовать его в bitmap

Мне нужно иметь возможность создать «Player p» с данными от прослушивателя и записью карты. До сих пор я терпел неудачу (не могу передать оба).

 //Method to create the list of players. To do: call again after adding new player
public void createPlayerList(){
    //The list of players that will be filled
    final List listPlayers = new ArrayList<Player>();

    //The path where all our players are stored.
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users")
            .child( FirebaseAuth.getInstance().getCurrentUser().getUid() ).child("team").child("players");


    //Method that just gets called once
    ref.addListenerForSingleValueEvent(new ValueEventListener() {

        //dataSnapshot contains all data from the path to our players
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Map<String, Object> players = (Map<String, Object>) dataSnapshot.getValue();

            //We return our player data in a map. Loop through each value in the map and create a player object for each player
            //And add that player object to our list of players

            //Create Storage instance
            FirebaseStorage storage = FirebaseStorage.getInstance();
            //Create storageReference
            final StorageReference storageRef = storage.getReferenceFromUrl("gs://bucket.appspot.com");

            // Create a reference to a file from a Google Cloud Storage URI
            StorageReference gsReference = storage.getReferenceFromUrl(storageRef   "/players/");


            for (Map.Entry<String, Object> entry : players.entrySet()){
                Map singlePlayer = (Map) entry.getValue();

                //Get unique key
                String key = entry.getKey();

                storageRef.child(key).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        //Picasso.with(getActivity()).load(uri).into(R.id.playerProfilePicture);
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception exception) {
                        // Handle any errors
                    }
                });

                //standard mage
                Bitmap profileBits = BitmapFactory.decodeResource(getResources(), R.drawable.player_icon);
                PlayersFragment.this.setProfilePicture(profileBits);

                //Create player
                Player p = new Player((String) singlePlayer.get("name"), (String) singlePlayer.get("preferredPosition"), profilePicture   );

                //Add player to list
                listPlayers.add(p);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    //Add all results from database to our listview
    listViewPlayers = (ListView) fragmentView.findViewById(R.id.players_list);

    //Attach adapter to listview, to get a layout for each row
    listViewPlayers.setAdapter(new PlayerAdapter(getActivity(), R.layout.row_player_list_item, listPlayers));
    //Necessary for handling clicks
    listViewPlayers.setItemsCanFocus(true);

}
  

Ответ №1:

Помните, что addListenerForSingleValueEvent возвращается немедленно. Прослушиватель, который вы передаете ему, будет вызван некоторое время спустя. В нынешнем виде, похоже, вы ожидаете, что оно будет блокироваться до тех пор, пока не будет доступен результат и listPlayers не будет полностью заполнен.

Вместо этого я предлагаю обращаться к listViewPlayers из вашего обратного вызова onDataChange сразу после того, как станет известно, что ваш список игроков заполнен.

Также обратите внимание, что gsReference, похоже, нигде не используется. Вы уверены, что не хотели сказать gsReference.child(key).getDownloadUrl()... , что нужно искать в папке «players» каждого найденного игрока в цикле?