我是android studio和firestore数据库的新手, 查询第二个Firestore集合时遇到一些麻烦。如标题所示,我要查询两个集合,第一个是:
代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
class RemainderFixed(axes_size.Scaled):
def __init__(self, xsizes, ysizes, divider):
self.xsizes =xsizes
self.ysizes =ysizes
self.div = divider
def get_size(self, renderer):
xrel, xabs = axes_size.AddList(self.xsizes).get_size(renderer)
yrel, yabs = axes_size.AddList(self.ysizes).get_size(renderer)
bb = Bbox.from_bounds(*self.div.get_position()).transformed(self.div._fig.transFigure)
w = bb.width/self.div._fig.dpi - xabs
h = bb.height/self.div._fig.dpi - yabs
return 0, min([w,h])
x = np.random.normal(512, 112, 240)
y = np.random.normal(0.5, 0.1, 240)
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
margin_size = axes_size.Fixed(1)
pad_size = axes_size.Fixed(.1)
xsizes = [pad_size, margin_size]
ysizes = xsizes
xhax = divider.append_axes("top", size=margin_size, pad=pad_size, sharex=ax)
yhax = divider.append_axes("right", size=margin_size, pad=pad_size, sharey=ax)
divider.set_horizontal([RemainderFixed(xsizes, ysizes, divider)] + xsizes)
divider.set_vertical([RemainderFixed(xsizes, ysizes, divider)] + ysizes)
ax.scatter(x, y)
xhax.hist(x)
yhax.hist(y, orientation="horizontal")
plt.setp(xhax.get_xticklabels(), visible=False)
plt.setp(yhax.get_yticklabels(), visible=False)
plt.show()
和第二个集合具有以下格式:
代码:
firestore = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.build();
firestore.setFirestoreSettings(settings);
firestore.collection("Obiective").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
//<--------- Check if firestore entry is already downloaded into file --------->
SingletonObjectivesId.getInstance().getIds().clear();
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, task.getResult().size() + " number of documents");
SingletonObjectivesId.getInstance().setSize(task.getResult().size());
if(document.exists() && document != null) { ...
您可以在第二个代码中看到,我添加了一个Log.d(在if(task.isSuccessful())之后),该文件将显示文档数。就我而言,第一个查询Log.d返回3,而第二个查询返回0,尽管我在那里有2个文档。如何访问这两个文档?
谢谢。
答案 0 :(得分:2)
Firebase API是异步的,这意味着onComplete()
方法在被调用后立即返回,并且它返回的Task中的回调将在一段时间后被调用。无法保证需要多长时间。因此,可能需要几百毫秒到几秒钟的时间才能获得该数据。由于该方法会立即返回,因此您尚未尝试记录的文档数尚未从回调中填充。
基本上,您正在尝试从异步的API同步使用值。那不是一个好主意。您应该按预期异步处理API。
此问题的快速解决方案是将查询第二个集合的代码移动到称为嵌套查询的第一个回调(在onComplete()
方法内部)内,否则,建议您查看我的最后一部分 post 中的答案,在此我解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。
答案 1 :(得分:0)
按照视频中的步骤操作后,我更新了如下代码:
我在课堂开始时创建了一个全局变量firestore
private FirebaseFirestore firestore;
我有两个方法readDataObjective和readDataRoute以及两个接口FirestoreCallback和FirestoreCallbackRoutes
readDataRoutes
private void readDataRoute(FirestoreCallbackRoute firestoreCallbackRoute){
firestore.collection("Trasee").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) { ...
readDataObjective
private void readDataObjective(FirestoreCallback firestoreCallback){
firestore.collection("Obiective").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
SingletonObjectivesId.getInstance().getIds().clear();
for (QueryDocumentSnapshot document : task.getResult()) { ...
接口
private interface FirestoreCallback{
void onCallback(ArrayList<Objective> list);
}
private interface FirestoreCallbackRoute{
void onCallback(ArrayList<Route> list);
}
在onCreate方法中,我这样调用readDataObjective和readDataRoute
firestore = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().build();
firestore.setFirestoreSettings(settings);
readDataObjective(new FirestoreCallback() {
@Override
public void onCallback(ArrayList<Objective> list) {
for(Objective item : list){
//Create plainText Object - delimiter "/~/"
String data = "Title:" + item.getTitle() + "/~/" +
............................
} else if(str.contains("Longitude:")){
obj.setLongitude(str.substring(10,str.length()));
}
start = crt + 2;
}
}
SingletonObjectivesArray.getInstance().getObjectives().add(obj);
}
readDataRoute(new FirestoreCallbackRoute() {
@Override
public void onCallback(ArrayList<Route> list) {
Log.d(TAG, 2 + " ");
ArrayList<Objective> routeObjectives = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
routeObjectives.clear();
for (int j = 0; j < SingletonObjectivesArray.getInstance().getObjectives().size(); j++){ ...
提到了readDataRoute在readDataObjective内部被调用。
我注意到问题不仅出在第二个查询上,而且也出在第一个查询上。我在第一个集合中添加了一个新文档,并在运行代码之后,第一个查询返回了旧数据(没有我的新条目)。