0

I upgraded my app to Flutter 2 and made all the things null safe. After that, I am encountering an error implementing Google mobile ads SDK.

I followed all the documentation and according to that, I am not supposed to get this error although the documentation is not updated. Here is the code in which I am trying to implement ads.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:book_rent_app_chapter3/model/order.dart';
import 'package:book_rent_app_chapter3/provider/user.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';


class OrdersScreen extends StatefulWidget {
  OrdersScreen({Key? key}) : super(key: key);

  @override
  State<OrdersScreen> createState() => _OrdersScreenState();
}

class _OrdersScreenState extends State<OrdersScreen> {
  BannerAd? _bannerAd;

  @override
  void initState() {
    super.initState();
    _bannerAd = BannerAd(
      adUnitId: BannerAd.testAdUnitId,
      request: AdRequest(),
      size: AdSize.banner,
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) {
          print('$BannerAd loaded.');
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          print('$BannerAd failedToLoad: $error');
        },
        onAdOpened: (Ad ad) => print('$BannerAd onAdOpened.'),
        onAdClosed: (Ad ad) => print('$BannerAd onAdClosed.'),
      ),
    );

    _bannerAd?.load();
  }

  @override
  void dispose() {
    super.dispose();
    _bannerAd?.dispose();
    _bannerAd = null;
  }

  @override
  Widget build(BuildContext context) {
    final userProvider = Provider.of<UserProvider>(context);
    return Scaffold(
      appBar: AppBar(
        iconTheme: const IconThemeData(color: Colors.black),
        backgroundColor: Colors.white,
        elevation: 0.0,
        title:
        const Text(
            "Orders", style: TextStyle(fontSize: 18, color: Colors.black)),
        leading: IconButton(
            icon: const Icon(Icons.close),
            onPressed: () {
              Navigator.pop(context);
            }),
      ),
      backgroundColor: Colors.white,
      body: Column(
        children:[ ListView.builder(
            itemCount: userProvider.orders.length,
            itemBuilder: (_, index) {
              OrderModel _order = userProvider.orders[index];
              return ListTile(
                leading: Text(
                  "\$${_order.total}",
                  style: const TextStyle(fontSize: 15, color: Colors.black),
                ),
                title: Text(_order.description),
                subtitle: Text(
                    DateTime.fromMillisecondsSinceEpoch(_order.createdAt)
                        .toString()),
                trailing: Text(_order.status,
                    style: const TextStyle(fontSize: 18, color: Colors.black)),
              );
            }),
          Container(
            alignment: Alignment.center,
            child: AdWidget(ad: _bannerAd),
            width: _bannerAd?.size.width.toDouble(),
            height: _bannerAd?.size.height.toDouble(),
          )
        ]
      ),
    );
  }
}

The error I am encountering is in the line

    child: AdWidget(ad: _bannerAd),

and the error is :

The argument type 'BannerAd?' can't be assigned to the parameter type 'AdWithView'. 

Although according to the documentation that's how exactly I am supposed to implement it.

halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

5

The problem with your code is simple, the ad is nullable, this means you can't just assign it into a widget ad because it would give you an error if it was null.

Looking at your code, your ad is only ever null before initstate or after dispose method, so you should not have any problems with a null ad during build, if that is the case, you can safely use ! to tell dart that the ad is not null:

child: AdWidget(ad: _bannerAd!),
h8moss
  • 4,626
  • 2
  • 9
  • 25