I'm trying to conditionally show a login button or the users avatar image, depending whether the user is logged in or not.
This simple example shows the user image after signing in and manually reloading the site:
class _LoginState extends State<Login> {
User? user = FirebaseAuth.instance.currentUser;
@override
Widget build(BuildContext context) {
return AppBar(
title: const Text('Foobar'),
actions: [
user == null
? const IconButton(
onPressed: signInWithGoogle, icon: Icon(Icons.login))
: CircleAvatar(
backgroundImage: NetworkImage(user!.photoURL!),
radius: 20,
)
],
);
}
}
I want the image to show automatically but with the following code, the image doesn't load at all anymore:
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return AppBar(
title: const Text('Foobar'),
actions: [
StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
if (snapshot.hasData) {
return CircleAvatar(
backgroundImage: NetworkImage(snapshot.data!.photoURL!),
radius: 20,
);
} else {
return const IconButton(
onPressed: signInWithGoogle, icon: Icon(Icons.login));
}
})
],
);
}
}
Instead I'm presented with the following error:
══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
The following ImageCodecException was thrown resolving an image codec:
Failed to load network image.
Image URL: https://lh3.googleusercontent.com/a/f00bar=s96-c
Trying to load an image from another domain? Find answers at:
https://flutter.dev/docs/development/platform-integration/web-images
When the exception was thrown, this was the stack
Image provider:
NetworkImage("https://lh3.googleusercontent.com/a/f00bar=s96
-c",
scale: 1)
Image key:
NetworkImage("https://lh3.googleusercontent.com/a/f00bar=s96
-c",
scale: 1)
════════════════════════════════════════════════════════════════════════════════════════════════════
Why does the first example load the image, but the second doesn't?
CodePudding user response:
Never build the stream in the stream:
parameter of the StreamBuilder. It must be part of State. Declare it in State, and initialize it in initState()
.
I must say this about FutureBuilder and StreamBuilder at least three times per week, so I made this video to demonstrate the problem.