firebase 存储 java.lang.IllegalStateException:任务尚未完成
firebase storage java.lang.IllegalStateException: Task is not yet complete
我想从 android 上的 firebase 文件夹下载我的所有文件。
this is my code
try {
StorageReference reference = storage.getReference().child("Ringtone");
reference.listAll().addOnCompleteListener(new OnCompleteListener<ListResult>() {
@Override
public void onComplete(@NonNull Task<ListResult> task) {
if (task.isComplete()){
task.addOnSuccessListener(new OnSuccessListener<ListResult>() { /////line 82 == 1st line where i am getting error
@Override
public void onSuccess(ListResult listResult) {
for (StorageReference item : listResult.getItems()) {
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(item.getDownloadUrl().getResult()); /////line 88 == 2nd line where i am getting error here
item.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
ringtoneModel.setSongName(storageMetadata.getName());
Toast.makeText(MainActivity.this, "ring name saved", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("metadata error",e.getMessage());
}
});
}
}
});}else {
Toast.makeText(MainActivity.this, (CharSequence) task.getException(), Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("list all error",e.getMessage());
}
}); }catch (Exception e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("all errors",e.getMessage());}
}
Logcat error message
/com.example.alarm E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.alarm, PID: 433
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source)
at com.google.android.gms.tasks.zzu.zzb(Unknown Source)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source)
at com.example.alarm.MainActivity.onSuccess(MainActivity.java:88)
at com.example.alarm.MainActivity.onSuccess(MainActivity.java:82)
我在 firebase 数据库中的文件夹和文件路径
Firebase storage >Rington<my files
<--我试过的-->
我尝试添加 addonsuuccesslistner , addoncompletelitner, task.isComplete(), task.issuccessfull() 以及更多东西
虽然 addOnSuccessListener
and addOnFailureListener
对于处理异步任务的结果很有用,但当您像这里一样需要将事物链接在一起时,它们就不是很有用了。
查看您的代码,您调用了以下行:
StorageReference item;
item.getDownloadUrl().getResult()
你得到的异常被抛出是因为你在调用 getResult()
.
之前没有等待这个任务完成
Task<String> downloadUrlTask = item.getDownloadUrl();
downloadUrlTask
.addOnSuccessListener(result -> {
// now do something with result
})
.addOnFailureListener(e -> {
// now do something with the exception
});
虽然上面的代码很有用,如果这就是您所需要的,您要做的是等待它与 getMetadata()
一起完成,这样您就可以创建 RingtoneModel
class.
这是 Tasks
实用程序 class 的用武之地。
Tasks.whenAll(Collection<Task<?>> tasks)
只有在 tasks
中的所有任务都成功完成后才会成功。
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.addOnSuccessListener(() -> { // then assemble its RingtoneModel
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
// we've now got a RingtoneModel! but what to do with it?
});
而不是在上面的代码中使用 addOnSuccessListener()
,如果我们使用 onSuccessTask()
we can return the RingtoneModel
back so that the Task<void>
from Tasks.whenAll()
is now a Task<RingtoneModel>
. To do this, we need to use Tasks.forResult()
,它将把我们的 RingtoneModel
变成 Task<RingtoneModel>
.
// function that takes a StorageReference and
// returns a task that resolves to a RingtoneModel
StorageReference item -> {
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.onSuccessTask(() -> { // then assemble its RingtoneModel
RingtoneModel ringtoneModel = new RingtoneModel();
// because these task have finished by now,
// you can safely use getResult() here
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
return Tasks.forResult(ringtoneModel);
});
}
现在我们有一个 StorageReference
的 RingtoneModel
,我们想把 List<StorageReference>
变成 List<RingtoneModel>
。我们可以使用
List<Task<RingtoneModel>> getRingtoneTasks = listResult.getItems()
.stream()
.map(convertToRingtoneModel); // the function above
注意这里我们有 List<Task<RingtoneModel>>
而不是 Task<List<RingtoneModel>>
。为了反过来,我们再次使用 Tasks.whenAll()
、onSuccessTask()
、stream().map()
和 Tasks.forResult()
。
return Tasks
.whenAll(getRingtoneTasks)
.onSuccessTask(() -> {
return Tasks.forResult(
getRingtoneTasks
.stream()
.map(task -> task.getResult());
);
});
现在您可能会看到上面的那个块,并认为这是一个非常巧妙的方法,可以用作实用方法,您是对的,因为您可以使用它来做同样的事情:
return Tasks.whenAllSuccess(getRingtoneTasks);
将所有这些混合在一起,得到:
public Task<List<RingtoneModel>> getRingtones() {
StorageReference reference = storage.getReference().child("Ringtone");
return reference.listAll() // find all objects under /Ringtone
.onSuccessTask(listResult -> {
// for each item found, assemble a RingtoneModel
List<Task<RingtoneModel>> getRingtoneTasks = listResult.getItems()
.stream()
.map((item) -> {
// A RingtoneModel needs the download URL and the object's metadata
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.onSuccessTask(() -> { // then assemble the RingtoneModel and return it
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
return Tasks.forResult(ringtoneModel);
});
});
return Tasks.whenAllSuccess(getRingtoneTasks);
});
}
那么当您想要获取云存储中的所有铃声时,您只需要:
getRingtones()
.addOnSuccessListener(ringtoneModelList -> {
Toast.makeText(MainActivity.this, "Found " + ringtoneModelList.size() + " ringtones.", Toast.LENGTH_SHORT).show();
// I recommend storing ringtoneModelList in your database of choice
})
.addOnFailureListener(e -> {
Toast.makeText(MainActivity.this, "Failed to get any ringtones.", Toast.LENGTH_SHORT).show();
Log.e("getRingtones error", e); // <-- log the full error to help with debugging
});
我想从 android 上的 firebase 文件夹下载我的所有文件。
this is my code
try {
StorageReference reference = storage.getReference().child("Ringtone");
reference.listAll().addOnCompleteListener(new OnCompleteListener<ListResult>() {
@Override
public void onComplete(@NonNull Task<ListResult> task) {
if (task.isComplete()){
task.addOnSuccessListener(new OnSuccessListener<ListResult>() { /////line 82 == 1st line where i am getting error
@Override
public void onSuccess(ListResult listResult) {
for (StorageReference item : listResult.getItems()) {
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(item.getDownloadUrl().getResult()); /////line 88 == 2nd line where i am getting error here
item.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
ringtoneModel.setSongName(storageMetadata.getName());
Toast.makeText(MainActivity.this, "ring name saved", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("metadata error",e.getMessage());
}
});
}
}
});}else {
Toast.makeText(MainActivity.this, (CharSequence) task.getException(), Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("list all error",e.getMessage());
}
}); }catch (Exception e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("all errors",e.getMessage());}
}
Logcat error message
/com.example.alarm E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.alarm, PID: 433
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source)
at com.google.android.gms.tasks.zzu.zzb(Unknown Source)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source)
at com.example.alarm.MainActivity.onSuccess(MainActivity.java:88)
at com.example.alarm.MainActivity.onSuccess(MainActivity.java:82)
我在 firebase 数据库中的文件夹和文件路径
Firebase storage >Rington<my files
<--我试过的--> 我尝试添加 addonsuuccesslistner , addoncompletelitner, task.isComplete(), task.issuccessfull() 以及更多东西
虽然 addOnSuccessListener
and addOnFailureListener
对于处理异步任务的结果很有用,但当您像这里一样需要将事物链接在一起时,它们就不是很有用了。
查看您的代码,您调用了以下行:
StorageReference item;
item.getDownloadUrl().getResult()
你得到的异常被抛出是因为你在调用 getResult()
.
Task<String> downloadUrlTask = item.getDownloadUrl();
downloadUrlTask
.addOnSuccessListener(result -> {
// now do something with result
})
.addOnFailureListener(e -> {
// now do something with the exception
});
虽然上面的代码很有用,如果这就是您所需要的,您要做的是等待它与 getMetadata()
一起完成,这样您就可以创建 RingtoneModel
class.
这是 Tasks
实用程序 class 的用武之地。
Tasks.whenAll(Collection<Task<?>> tasks)
只有在 tasks
中的所有任务都成功完成后才会成功。
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.addOnSuccessListener(() -> { // then assemble its RingtoneModel
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
// we've now got a RingtoneModel! but what to do with it?
});
而不是在上面的代码中使用 addOnSuccessListener()
,如果我们使用 onSuccessTask()
we can return the RingtoneModel
back so that the Task<void>
from Tasks.whenAll()
is now a Task<RingtoneModel>
. To do this, we need to use Tasks.forResult()
,它将把我们的 RingtoneModel
变成 Task<RingtoneModel>
.
// function that takes a StorageReference and
// returns a task that resolves to a RingtoneModel
StorageReference item -> {
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.onSuccessTask(() -> { // then assemble its RingtoneModel
RingtoneModel ringtoneModel = new RingtoneModel();
// because these task have finished by now,
// you can safely use getResult() here
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
return Tasks.forResult(ringtoneModel);
});
}
现在我们有一个 StorageReference
的 RingtoneModel
,我们想把 List<StorageReference>
变成 List<RingtoneModel>
。我们可以使用
List<Task<RingtoneModel>> getRingtoneTasks = listResult.getItems()
.stream()
.map(convertToRingtoneModel); // the function above
注意这里我们有 List<Task<RingtoneModel>>
而不是 Task<List<RingtoneModel>>
。为了反过来,我们再次使用 Tasks.whenAll()
、onSuccessTask()
、stream().map()
和 Tasks.forResult()
。
return Tasks
.whenAll(getRingtoneTasks)
.onSuccessTask(() -> {
return Tasks.forResult(
getRingtoneTasks
.stream()
.map(task -> task.getResult());
);
});
现在您可能会看到上面的那个块,并认为这是一个非常巧妙的方法,可以用作实用方法,您是对的,因为您可以使用它来做同样的事情:
return Tasks.whenAllSuccess(getRingtoneTasks);
将所有这些混合在一起,得到:
public Task<List<RingtoneModel>> getRingtones() {
StorageReference reference = storage.getReference().child("Ringtone");
return reference.listAll() // find all objects under /Ringtone
.onSuccessTask(listResult -> {
// for each item found, assemble a RingtoneModel
List<Task<RingtoneModel>> getRingtoneTasks = listResult.getItems()
.stream()
.map((item) -> {
// A RingtoneModel needs the download URL and the object's metadata
Task<String> downloadUrlTask = item.getDownloadUrl();
Task<StorageMetadata> metadataTask = item.getMetadata();
return Tasks
.whenAll([ // wait for these tasks to finish successfully
downloadUrlTask,
metadataTask
])
.onSuccessTask(() -> { // then assemble the RingtoneModel and return it
RingtoneModel ringtoneModel = new RingtoneModel();
ringtoneModel.setUri(downloadUrlTask.getResult());
ringtoneModel.setSongName(metadataTask.getResult().getName());
return Tasks.forResult(ringtoneModel);
});
});
return Tasks.whenAllSuccess(getRingtoneTasks);
});
}
那么当您想要获取云存储中的所有铃声时,您只需要:
getRingtones()
.addOnSuccessListener(ringtoneModelList -> {
Toast.makeText(MainActivity.this, "Found " + ringtoneModelList.size() + " ringtones.", Toast.LENGTH_SHORT).show();
// I recommend storing ringtoneModelList in your database of choice
})
.addOnFailureListener(e -> {
Toast.makeText(MainActivity.this, "Failed to get any ringtones.", Toast.LENGTH_SHORT).show();
Log.e("getRingtones error", e); // <-- log the full error to help with debugging
});