Rub*_*uez 5 java android firebase google-cloud-firestore
我列出了从我的Cloud Firestore数据库获取值的POJO对象列表。这个列表本身就是一个类,每当我创建一个新的列表时都会记住要检索属性。事实是,列表不是在创建活动中填写的,而是之后的时间。我尝试添加循环,任务,等待,但未获得所需的结果。这是我令人满意地检索数据的方式:
private void retrieveData(){
reference = firestore.collection("attractions");
reference.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
@Nullable FirebaseFirestoreException e) {
attractionList.clear();
for (DocumentSnapshot snapshot : queryDocumentSnapshots) {
Attraction attraction = snapshot.toObject(Attraction.class);
addAttractions(attraction);
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
每次创建新对象时,我都会检索数据:
public AttractionList() {
firestore.setFirestoreSettings(settings);
reference = firestore.collection("attractions");
attractionList = new ArrayList<>();
retrieveData();
}
Run Code Online (Sandbox Code Playgroud)
然后,如果我在创建时在我的活动中检查列表大小:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_attraction);
Toolbar toolbar = findViewById(R.id.tb_attraction);
setSupportActionBar(toolbar);
//Creating POJO List and retrieving data
attractionList = new AttractionList();
Log.e("List Size: ", ""+attractionList.getAttractionList().size());
//List Size: 0
}
Run Code Online (Sandbox Code Playgroud)
但是,如果之后使用相同的Log time,则在任何按钮中:
@Override
public void onBackPressed(){
Log.e("List Size: ", ""+attractionList.getAttractionList().size());
//List Size: 16
}
Run Code Online (Sandbox Code Playgroud)
我并不是很想在每个Activity中检索数据,也不想创建将Object带入Activity之间的意图。有什么办法可以解决这个问题?
PS:这是我的第一篇文章。抱歉,如果我没有以正确的方式进行操作。非常感谢。
您现在不能使用尚未加载的内容。Firestore会加载数据asynchronously,因为这可能需要一些时间。根据您的连接速度和状态,可能需要几百毫秒到几秒钟的时间才能获得该数据。如果要将类型的对象列表传递Attraction给另一个方法,只需在方法内部调用该方法onSuccess()并将该列表作为参数传递。因此,一个快速的解决方法是:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference attractionsRef = rootRef.collection("attractions");
attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<Attraction> attractionsList = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
Attraction attraction = document.toObject(Attraction.class);
attractionsList.add(attraction);
}
methodToProcessTheList(attractionsList);
}
}
});
Run Code Online (Sandbox Code Playgroud)
因此请记住,onSuccess()方法具有异步行为,这意味着甚至在从数据库获取数据之前就已调用该方法。如果要使用该attractionsList方法之外的方法,则需要创建自己的方法callback。为此,首先需要创建一个如下接口:
public interface MyCallback {
void onCallback(List<Attraction> attractionsList);
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要创建一个实际上从数据库获取数据的方法。此方法应如下所示:
public void readData(MyCallback myCallback) {
attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<Attraction> attractionsList = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
Attraction attraction = snapshot.toObject(Attraction.class);
attractionsList.add(attraction);
}
myCallback.onCallback(attractionsList);
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
最后,仅需简单地调用readData()method并将MyCallback接口的实例作为参数传递给您,如您所需要的那样:
readData(new MyCallback() {
@Override
public void onCallback(List<Attraction> attractionsList) {
//Do what you need to do with your list
}
});
Run Code Online (Sandbox Code Playgroud)
这是可以attractionsList在onSuccess()方法外部使用该对象的唯一方法。有关更多信息,您也可以观看此视频。