skip to Main Content

I am trying to retrieve an string url from FirebaseFirestore.

My code for UI is as follows

Container(
                                                  height: 65,
                                                  width: 65,
                                                  decoration: BoxDecoration(
                                                      border: Border.all(
                                                          width: 8,
                                                          color: const Color
                                                              .fromARGB(
                                                              255, 3, 54, 95)),
                                                      shape: BoxShape.circle,
                                                      color: Colors.black38),
                                                  child: ClipRRect(
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            22),
                                                    child: CachedNetworkImage(
                                                      imageUrl:
                                                          model.photoUrl,
                                                      fit: BoxFit.cover,

The code is trying to access a variable from the provider file, which is as follows:

 photoUrl = AuthMethods().getPhotoUrl().toString();

//Authomethods file

Future<String> getPhotoUrl() async {
    DocumentSnapshot snap = await FirebaseFirestore.instance
        .collection('users')
        .doc(FirebaseAuth.instance.currentUser!.uid)
        .get();

final String photoUrl = (snap.data() as Map<String, dynamic>)['photoUrl'];
return photoUrl;
// return photoUrl;

}

3

Answers


  1. getPhotoUrl() is an async function and needs to be awaited to. It could only work if instead of

    photoUrl = AuthMethods().getPhotoUrl().toString();
    

    you instead write

    photoUrl = await AuthMethods().getPhotoUrl();
    

    Although this can only be called like that in another async which you might not have

    Login or Signup to reply.
  2. Async Data Retrieval: getPhotoUrl is an asynchronous function, meaning it returns a Future. The line where you’re assigning photoUrl isn’t awaiting that future, hence the problem.

    Provider/Model Updates: If you’re using a provider or any state management solution, ensure that you notify listeners when updating photoUrl so that the UI rebuilds with the new data.

    Using FutureBuilder: Since you’re dealing with asynchronous data retrieval, consider using FutureBuilder for better handling of the future state.

    Here’s how you can do it:

    In your UI (where you want to display the image):

    FutureBuilder<String>(
      future: AuthMethods().getPhotoUrl(),
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            // Return an error widget or something else if the Future fails
            return Text('Error: ${snapshot.error}');
          }
          // Once the Future is complete and no errors occurred,
          // display the created image
          return Container(
            height: 65,
            width: 65,
            decoration: BoxDecoration(
              border: Border.all(width: 8, color: const Color.fromARGB(255, 3, 54, 95)),
              shape: BoxShape.circle,
              color: Colors.black38,
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(22),
              child: CachedNetworkImage(
                imageUrl: snapshot.data!,
                fit: BoxFit.cover,
              ),
            ),
          );
        } else {
          // While the Future is running, show a loading indicator
          return CircularProgressIndicator();
        }
      },
    )
    

    In your AuthMethods:

    Ensure error handling if the photoUrl doesn’t exist in the document or if there are any other issues during the fetch.

    With this setup, the FutureBuilder will handle the lifecycle of your asynchronous function. It will show a loading indicator while fetching the data, display the image once the data is fetched, or handle errors if they occur.

    Login or Signup to reply.
  3. Before using your Url, you can call your Container by checking it to avoid asynchronous data pull problems. For example:

    Widget get customImage {
        return renderUrl == null ?
          Container() :
          Container(
            width: 100.0,
            height: 100.0,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage(renderUrl),
              ),
            ),
          );
      }
    

    Alternative:

    Add https:// before your uri

    You can also review this answers: Invalid argument(s): No host specified in URI – Image.network

    I hope I have helped. Enjoy your work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search