I have to fetch ta video URL store in FireStore before displaying the video itself.
I used a FutureBuilder
in my build to do so:
if (ad.videoUrl != null)
FutureBuilder(
future: Video.videoUrl("blabla"), //ad.videoUrl!),
builder: (context, snapshot) {
if (snapshot.hasData) {
final url = snapshot.data;
return Text(url ?? "No video found");
} else {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Text("Searching the video on the cloud"),
CircularProgressIndicator()
]);
}
}),
The future itself is straightforward:
/// Fetches the video url from the video [name]
static Future<String?> videoUrl(String name) {
final videoBucket =
FirebaseStorage.instanceFor(bucket: Globals.storageBucketUrl);
final videoBucketRef = videoBucket.ref();
final item = videoBucketRef.child(name);
return item.getDownloadURL();
}
And like this, I've got what I want. Perfect.
But now, I want to handle the exception within the future so that it returns null when any occur.
I've updated my code as follows:
/// Fetches the video url from the video [name]
static Future<String?> videoUrl(String name) async {
final videoBucket =
FirebaseStorage.instanceFor(bucket: Globals.storageBucketUrl);
final videoBucketRef = videoBucket.ref();
try {
final item = videoBucketRef.child(name);
return await item.getDownloadURL();
} catch (e) {
return null;
}
Though the exception is caught as expected (when I fetch a video name that does not exist), it looks like the future never returns a value (neither null or the URL when it exists.
Therefore what's wrong in my code?
Note: Btw, I have also tried this without success when the exception occurs, though it is ok for an existing video name.
/// Fetches the video url from the video [name]
static Future<String?> videoUrl(String name) async {
final videoBucket =
FirebaseStorage.instanceFor(bucket: Globals.storageBucketUrl);
final videoBucketRef = videoBucket.ref();
try {
final item = videoBucketRef.child(name);
final url = await item.getDownloadURL();
return Future<String?>.value(name);
} catch (e) {
return Future<String?>.value(null);
}
CodePudding user response:
instead of returning null
, you can throw an exception like this:
catch (e) {
throw Exception("some error here");
}
inside the FutureBuilder
you can use the hasError
to show some widget based on it:
FutureBuilder(
future: Video.videoUrl("blabla"), //ad.videoUrl!),
builder: (context, snapshot) {
if (snapshot.hasData) {
final url = snapshot.data;
return Text(url ?? "No video found");
} else if(snapshot.hasError) {
return Text("error ${snapshot.error}");
} else{
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Text("Searching the video on the cloud"),
CircularProgressIndicator()
]);
}
}),