imsamgarg / firebase_cached_image

Cache Manager and Cached ImageProvider for Firebase Cloud Storage Objects.
MIT License
9 stars 16 forks source link

Fixing _TypeError when switching between #11

Closed bartdelange closed 1 year ago

bartdelange commented 1 year ago

Using covariant in this way disallows us to switch between image providers (useful when for example you want to check if a firestore document has a field set with an image and if not display a placeholder). This is because DecorationImage and the like use an equals check on their image provider.

As shown in error below, which was thrown when switching between an asset image and the firebase image:

======== Exception caught by widgets library ======================================================= The following _TypeError was thrown building Builder(dirty, dependencies: [Directionality, MediaQuery, _LocalizationsScope-[GlobalKey#61773]]): type 'AssetImage' is not a subtype of type 'FirebaseImageProvider' of 'other'

The relevant error-causing widget was: 
  Ink Ink:file:///anon/lib/components/widget.dart:100:28
When the exception was thrown, this was the stack: 
#0      FirebaseImageProvider.== (package:firebase_cached_image/src/firebase_image_provider.dart)
#1      DecorationImage.== (package:flutter/src/painting/decoration_image.dart:196:24)
#2      BoxDecoration.== (package:flutter/src/painting/box_decoration.dart:329:24)
#3      InkDecoration.decoration= (package:flutter/src/material/ink_decoration.dart:355:15)
#4      _InkState._build (package:flutter/src/material/ink_decoration.dart:292:13)
#5      Builder.build (package:flutter/src/widgets/basic.dart:7448:48)
#6      StatelessElement.build (package:flutter/src/widgets/framework.dart:5038:49)
#7      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)

It should be reproducible with something like this:

import 'package:firebase_cached_image/firebase_cached_image.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class TestWidget extends StatefulWidget {
  const PlantCard({Key? key}) : super(key: key);

  @override
  State<PlantCard> createState() => _PlantCardState();
}

class _PlantCardState extends State<PlantCard> {
  late ImageProvider<Object> _image;

  @override
  void initState() {
    _setImage(const AssetImage('some-asset.jpeg')); // CHANGE ME

    super.initState();
  }

  void _setImage(ImageProvider<Object> imageProvider) {
    setState(() {
      _image = imageProvider;
    });
  }

  @override
  Widget build(BuildContext context) {
    print('${widget.plant.name}: ${widget.plant.imagePath}');
    return InkWell(
      onTap: () {
        _setImage(FirebaseImageProvider(
          FirebaseUrl.fromReference(firebaseRef), // CHANGE ME
        ));
      },
      child: Ink.image(
        image: _image,
        fit: BoxFit.cover,
      ),
    );
  }
}
imsamgarg commented 1 year ago

Ohh!! I completely forgot about that covariant keyword in the == override. Some vscode extension generated it. Anyways Thank you for the pull request. Merging it...🔗