gpt4 book ai didi

android - 使用 Firebase 从列表中查询每个节点的键

转载 作者:行者123 更新时间:2023-11-29 18:42:32 26 4
gpt4 key购买 nike

我有一个字符串列表,这个列表包含 Firebase 数据库中的节点名称。

我有一个自定义排序方法,因此我想在不使用 Firebase 查询排序函数的情况下获取自定义列表中每个节点的所有键。因此,我需要检索所有数据,因此在检索某些数据时添加到列表不是一种选择。

然而,问题始于 Firebase 的异步结构。

我遍历自定义列表中的每个节点名称,并在该循环下在 Firebase 线程 ( addListenerForSingleValueEvent ) 中创建另一个循环以检索所有键。但它是异步工​​作的。我试图通过使用 Thread 和 Semaphore 将其更改为同步,但没有成功。我还使用了自定义接口(interface) (FirebaseDataRetrieveListener) 来指示 valueEventListener 中的循环何时结束,但是由于 valueEventListener 立即返回,所以如果不暂停线程这是不可能的。

如果Task's可以在这种情况下使用,怎么可能,或者有没有其他解决方案?

private void getKeysFromNodeList(final FirebaseDataRetrieveListener listener) //TODO [BUG] when first for loop initializes it ignores the seperate thread in the inner anonymous class so it'll be already finished it's cycle before Firebase` loop starts...
{
listener.onStart();

final DatabaseReference databaseRef = firebaseInstance.rootRef.child(context.getString(R.string.databaseref));
for (iterator = 0; iterator < nodeList.size(); iterator ++)
{

Query query = databaseRed.child(nodeList.get(iterator));

query.addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{


for (DataSnapshot snap : dataSnapshot.getChildren())
{

iterator++;

String key= snap.getKey();
// I've done my jobs with given key here


// if got the last key from node and iterated the last node
if (firebaseIterator== dataSnapshot.getChildrenCount() - 1 && iterator == nodeList.size() - 1)
{


firebaseIterator= 0;// reset the iterators
iterator= 0;

listener.onSuccess();
break;
}
// if got the last key from node
else if (firebaseIterator== dataSnapshot.getChildrenCount() - 1)
{
firebaseIterator= 0; // reset the iterator

break;
}
}
}

@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
listener.onFailed(databaseError);
return;
}
});


}
;


}

}

FirebaseDataRetrieveListener.java

public interface FirebaseDataRetrieveListener
{
public void onStart();
public void onSuccess();
public void onFailed(DatabaseError databaseError);
}

最佳答案

基本上,您正在尝试从异步 API 同步返回一个值。那不是一个好主意。您应该按预期异步处理 API。暂停线程可能会解决您的问题,但只是部分解决。并且根本不推荐。

Firebase API 是异步,这意味着 onDataChange() 方法在被调用后立即返回,并且它返回的任务的回调将在一段时间后调用。无法保证需要多长时间。因此,在数据可用之前可能需要几百毫秒到几秒。因为该方法会立即返回,所以来自数据库的值还没有从回调中填充。

快速解决此问题的方法是仅在回调中使用这些值,否则我建议您从这个 post 中查看我的答案的最后一部分。 我在其中解释了如何使用自定义回调来完成。你也可以看看这个 video 以便更好地理解。

总而言之,无法将异步 API 转换为同步 API,因为 Firebase 是同步 API。

关于android - 使用 Firebase 从列表中查询每个节点的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52794708/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com