Home > other >  Argument type 'String?' cannot be assigned to parameter type 'String', Triggerin
Argument type 'String?' cannot be assigned to parameter type 'String', Triggerin

Time:04-29

In this current snippet I have declared notification to be nullable but get an null safe error for the if loop's notification.body and notification.title.

Here's my code:

      RemoteNotification? notification = message.notification;
      AndroidNotification? android = message.notification?.android;
      if (notification != null && android != null) {
        showDialog(
            context: context,
            builder: (_) {
              return AlertDialog(
                title: Text(notification.title),
                content: SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [Text(notification.body)],
                  ),
                ),
              );
            });

If I make 'notification' to be non nullable, I get the same null safe error.

Code:

      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;
      if (notification != null && android != null) {
        showDialog(
            context: context,
            builder: (_) {
              return AlertDialog(
                title: Text(notification.title),
                content: SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [Text(notification.body)],
                  ),
                ),
              );
            });

How to get this to work?

Any help appreciated!

CodePudding user response:

I'm assuming it's body and title that could be null. A solution is to fallback to empty strings in case they are, like this:

          return AlertDialog(
            title: Text(notification.title ?? ''),
            content: SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [Text(notification.body ?? '')],
              ),
            ),
          );

CodePudding user response:

A couple things going on here. First, the reason you are getting the null error:

RemoteNotification? notification = message.notification;

When notification is a nullable value, you will get the warning when you attempt to use it without first checking if it is null. Changing it to be non-nullable can resolve the problem, but potentially in a way you don't actually want.

Now when you changed it to non-nullable, you didn't change the line after it:

RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;

Now notification is no longer nullable, but you still use a null-coalescing operator when creating android. That means that, even though notification is non-nullable, android still is nullable. From this, you will get two warnings - one for trying to coalesce a non-nullable value, and one for using android without checking for null.

The easiest solution would be to make it so android is non-nullable as well:

RemoteNotification notification = message.notification;
AndroidNotification android = message.notification.android;

But this might not be possible depending on whether message.notification itself is nullable.


Now onto the second thing. Assuming we want notification and android to be nullable, your first null-check isn't enough to eliminate the warning within the callback to showDialog. This is because, even though it is known that when showDialog is called, notification is not null, the analyzer can't know when the callback itself will be called, and by that point, notification might have become null. For that reason, the analyzer has no choice but to display the warning regardless of your current null check.

There are four ways to resolve this. First, you could check for null again:

if (notification != null && android != null) {
  showDialog(
    context: context,
    builder: (_) {
      if (notification != null && android != null) {
        return AlertDialog(
          title: Text(notification.title),
          content: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [Text(notification.body)],
            ),
          ),
        );
      } else {
        // Return a different widget if null check fails
      }
    },
  );
}

Or force non-null with the ! operator:

if (notification != null && android != null) {
  showDialog(
    context: context,
    builder: (_) {
      return AlertDialog(
        title: Text(notification!.title),
        content: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [Text(notification!.body)],
          ),
        ),
      );
    },
  );
}

Or provide default values in the case that the objects are null:

if (notification != null && android != null) {
  showDialog(
    context: context,
    builder: (_) {
      return AlertDialog(
        title: Text(notification?.title ?? 'Default Value'),
        content: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [Text(notification?.body ?? 'Default Value')],
          ),
        ),
      );
    },
  );
}

Or make non-null versions of the objects that the callback can closure around:

if (notification != null && android != null) {
  final notificationNN = notification;
  final androidNN = android;
  showDialog(
    context: context,
    builder: (_) {
      return AlertDialog(
        title: Text(notificationNN.title),
        content: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [Text(androidNN.body)],
          ),
        ),
      );
    },
  );
}

CodePudding user response:

Try this:

...
title: Text(notification.title as String),
...
  • Related