在当前代码段中,我已将通知声明为可空,但对于if循环的通知,得到一个空安全错误。Body and notification.title.
下面是我的代码:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint('A new onMessageOpenedApp event was published!');
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)],
),
),
);
});
}
});
如果我将'notification'设置为非空,我将得到相同的空安全错误。
代码:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint('A new onMessageOpenedApp event was published!');
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)],
),
),
);
});
}
});
如何让这个工作?
感谢任何帮助!
编辑:将方法名称添加到编码部分。
这里发生了几件事。首先,您得到null错误的原因:
RemoteNotification? notification = message.notification;
当notification
是一个可空值时,当您尝试使用它而不首先检查它是否为空时,您将得到警告。将其更改为非空可以解决问题,但可能以一种您实际上不希望的方式。
现在当你把它改成non-nullable时,你没有改变它后面的行:
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;
现在notification
不再是空的,但你仍然使用空合并操作符创建android
。这意味着,即使notification
是非空的,android
仍然是空的。由此,您将得到两个警告——一个是试图合并一个不可为空的值,另一个是使用android
而不检查是否为空。
最简单的解决方案是使android
也不可为空:
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification.android;
但这可能不可能取决于message.notification
本身是否可为空。
现在来看第二件事。假设我们希望notification
和android
为空,那么您的第一个空检查不足以消除showDialog
回调中的警告。这是因为,即使知道在调用showDialog
时,notification
不为空,分析器也无法知道何时调用回调本身,到那时,notification
可能已经变为空。由于这个原因,分析器别无选择,只能显示警告,而不管当前的空检查。
有四种方法可以解决这个问题。首先,您可以再次检查是否为空:
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
}
},
);
}
或者使用!
运算符强制非空:
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 (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')],
),
),
);
},
);
}
或者创建回调可以闭包的对象的非空版本:
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)],
),
),
);
},
);
}
我假设它的主体和标题可以为空。一种解决方案是在它们是空字符串的情况下回退到空字符串,如下所示:
return AlertDialog(
title: Text(notification.title ?? ''),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(notification.body ?? '')],
),
),
);
试试这个:
...
title: Text(notification.title as String),
...