#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» каждого найденного игрока в цикле?