The following TypeErrorImpl was thrown building GameScreen - dart

I got this error on terminal
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ The
following TypeErrorImpl was thrown building GameScreen(dirty,
dependencies: [_InheritedProviderScope<RoomDataProvider?>], state:
_GameScreenState#df23f): type 'Null' is not a 'bool' in boolean expression The relevant error-causing widget was: GameScreen
This is my code:
import 'package:flutter/material.dart';
import 'package:game/provider/room_data_provider.dart';
import 'package:game/resources/socket_method.dart';
import 'package:provider/provider.dart';
import '../viiews/waiting_lobby.dart';
class GameScreen extends StatefulWidget {
static String routeName = '/game';
const GameScreen({Key? key}) : super(key: key);
#override
State<GameScreen> createState() => _GameScreenState();
}
class _GameScreenState extends State<GameScreen> {
final SocketMethods _socketMethods = SocketMethods();
#override
void initState() {
super.initState();
_socketMethods.updateRoomListener(context);
_socketMethods.updatePlayerStateListener(context);
// _socketMethods.pointIncreaseListener(context);
// _socketMethods.endGameListener(context);
}
#override
Widget build(BuildContext context) {
RoomDataProvider roomDataProvider = Provider.of<RoomDataProvider>(context);
return Scaffold(
body: roomDataProvider.roomData['isJoin']
? const WaitingLobby()
: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// const Scoreboard(),
// const TicTacToeBoard(),
Text(
'${roomDataProvider.roomData['turn']['nickname']}\'s turn'),
],
),
),
);
}
}
room_data_provider.dart
import 'package:flutter/material.dart';
import 'package:game/models/player.dart';
class RoomDataProvider extends ChangeNotifier {
Map<String, dynamic> _roomData = {};
Player _player1 =
Player(nickname: "", socketID: "", points: 0, playerType: "X");
Player _player2 =
Player(nickname: "", socketID: "", points: 0, playerType: "O");
Map<String, dynamic> get roomData => _roomData;
Player get player1 => _player1;
Player get player2 => _player2;
void updateRoomData(Map<String, dynamic> data) {
_roomData = data;
notifyListeners();
}
void updatePlayer1(Map<String, dynamic> player1Data) {
_player1 = Player.fromMap(player1Data);
notifyListeners();
}
void updatePlayer2(Map<String, dynamic> player2Data) {
_player2 = Player.fromMap(player2Data);
notifyListeners();
}
}
index.js
socket.on("joinRoom", async ({ nickname, roomId }) => {
try {
if (!roomId.match(/^[0-9a-fA-F]{24}$/)) {
socket.emit("errorOccurred", "Please enter a valid room ID.");
return;
}
let room = await Room.findById(roomId);
if (room.isJoin) {
let player = {
nickname,
socketID: socket.id,
playerType: "O",
};
socket.join(roomId);
room.players.push(player);
room.isJoin = false;
room = await room.save();
io.to(roomId).emit("joinRoomSuccess", room);
io.to(roomId).emit("updatePlayers", room.players);
io.to(roomId).emit("updateRoom", room);
} else {
socket.emit(
"errorOccurred",
"The game is in progress, try again later."
);
}
} catch (e) {
console.log(e);
}
});
How can I solve this issue ?
Thanks for any help you can provide

Related

flutter notification is not coming in ios when app is on kill state but when we open the app notification is coming

Hello i have an issue in flutter IOS notification , when app is on background or kill state notification is showing only when we click to open the app otherWise notification is not showing in IOS device !
Please try this
class name FCM
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> onBackgroundMessage(RemoteMessage message) async {
await Firebase.initializeApp();
if (message.data.containsKey('data')) {
// Handle data message
final data = message.data['data'];
}
if (message.data.containsKey('notification')) {
// Handle notification message
final notification = message.data['notification'];
}
// Or do other work.
}
class FCM {
final _firebaseMessaging = FirebaseMessaging.instance;
final streamCtlr = StreamController<String>.broadcast();
final titleCtlr = StreamController<String>.broadcast();
final bodyCtlr = StreamController<String>.broadcast();
setNotifications() {
FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
FirebaseMessaging.onMessage.listen(
(message) async {
if (message.data.containsKey('data')) {
// Handle data message
streamCtlr.sink.add(message.data['data']);
}
if (message.data.containsKey('notification')) {
// Handle notification message
streamCtlr.sink.add(message.data['notification']);
}
// Or do other work.
titleCtlr.sink.add(message.notification!.title!);
bodyCtlr.sink.add(message.notification!.body!);
},
);
// With this token you can test it easily on your phone
final token =
_firebaseMessaging.getToken().then((value) => print('Token: $value'));
}
dispose() {
streamCtlr.close();
bodyCtlr.close();
titleCtlr.close();
}
}
And Main Class
void main() async {
await init();
runApp(const MyApp1());
}
Future init() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String notificationTitle = 'No Title';
String notificationBody = 'No Body';
String notificationData = 'No Data';
#override
void initState() {
final firebaseMessaging = FCM();
firebaseMessaging.setNotifications();
firebaseMessaging.streamCtlr.stream.listen(_changeData);
firebaseMessaging.bodyCtlr.stream.listen(_changeBody);
firebaseMessaging.titleCtlr.stream.listen(_changeTitle);
super.initState();
}
_changeData(String msg) => setState(() => notificationData = msg);
_changeBody(String msg) => setState(() => notificationBody = msg);
_changeTitle(String msg) => setState(() => notificationTitle = msg);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
notificationTitle,
style: Theme.of(context).textTheme.headline4,
),
Text(
notificationBody,
style: Theme.of(context).textTheme.headline6,
),
Text(
notificationData,
style: Theme.of(context).textTheme.headline6,
),
],
),
),
);
}
}

StateError (Bad state: No element) on IOS only

This error does not occur on Android or web but only on IOS. It seem very trivial but I can't figure out what's wrong.
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'dart:convert';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class ScanQrPage extends StatefulWidget {
#override
_ScanQrPageState createState() => _ScanQrPageState();
}
class _ScanQrPageState extends State<ScanQrPage> {
final qrKey = GlobalKey();
late QRViewController qrViewController;
late Barcode barcode;
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
#override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
qrViewController.pauseCamera();
} else if (Platform.isIOS) {
qrViewController.resumeCamera();
}
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
Navigator.of(context).pop("");
return new Future(() => true);
},
child: Scaffold(
body: Stack(
children: [
buildQrView(context),
],
),
),
);
}
Widget buildQrView(BuildContext context) {
return QRView(
onQRViewCreated: onQRViewCreated,
key: qrKey,
overlay: QrScannerOverlayShape(
cutOutSize: MediaQuery.of(context).size.width * 0.8),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('no Permission')),
);
}
}
#override
void dispose() {
qrViewController.dispose();
super.dispose();
}
void onQRViewCreated(QRViewController qrViewController) {
setState(() {
this.qrViewController = qrViewController;
});
qrViewController.scannedDataStream.listen((event) {
setState(() {
this.barcode = event;
if (Platform.isAndroid) {
qrViewController.pauseCamera();
} else if (Platform.isIOS) {
qrViewController.resumeCamera();
}
String rawData = event.code;
Uri data = Uri.dataFromString(rawData);
String para1 = data.queryParameters["buy"] ??
""; //get parameter with attribute "para1"
Codec<String, String> stringToBase64 = utf8.fuse(base64);
if (para1 != "") {
placer = stringToBase64.decode(para1);
}
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
Navigator.pop(context, placer);
});
});
});
}
}
I've tried all the solutions with the same error found on stackoverflow (addPostFrameCallback and Future(Duration.zero)) but none of them are exactly the same and does not seem to fix my problem.
I don't think I have having the same issue as any of the other questions.
The exception is happening on the Navigator.pop(context, placer);
Does anyone have any idea how to overcome this?
Why does this only happen on IOS?

Flutter don't update UI from iOS using setState() method

I am invoking a method from native Swift code by using the platform channel like this:
channel.invokeMethod(METHOD_NAME, arguments: STRING_ARGUMENT)
in my Flutter class I handle the respective method call by using a callback
platform.setMethodCallHandler(_receiveFromHost);
The setMethodCallHandler() requires the callback to return a Future and I set state in _receiveFromHost method in Dart.
Problem is that my UI is not updated when Swift invokes the callback. Why?
call.method catch method string, state is set, but UI don't update.
video
This is my code in Swift:
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController = FlutterViewController(engine: flutterEngine!, nibName: nil, bundle: nil)
let channel = FlutterMethodChannel(name: "flutter_apple_pay", binaryMessenger: flutterViewController.binaryMessenger)
channel.invokeMethod("sendDidFinishAdding", arguments: "payment success")
And this is my code in Flutter:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'dart:convert';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text("Native Code from Dart"),
),
body: new MyHomePage(title: ""),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _state = "Waiting results...";
static const platform = const MethodChannel("flutter_apple_pay");
_MyHomePageState() {
platform.setMethodCallHandler(_receiveFromHost);
}
// #override
// void initState() {
// platform.setMethodCallHandler(_receiveFromHost);
// super.initState();
// }
Future<dynamic> _receiveFromHost(MethodCall call) async {
List certificatesBase64Encoded;
String nonceBase64Encoded;
String nonceSignatureBase64Encoded;
String state;
try {
print(call.method);
if (call.method == "sendGenerateRequestWithData") {
final String data = call.arguments;
final jData = jsonDecode(data);
certificatesBase64Encoded = jData['certificatesBase64Encoded'];
nonceBase64Encoded = jData['nonceBase64Encoded'];
nonceSignatureBase64Encoded = jData['nonceSignatureBase64Encoded'];
print(certificatesBase64Encoded);
print(nonceBase64Encoded);
print(nonceSignatureBase64Encoded);
state = "sendGenerateRequestWithData";
platform.invokeMethod("SendTokenizationData", "TokenizationDataString");
} else if (call.method == "sendDidFinishAdding") {
final String result = call.arguments;
print(result);
state = result;
}
} on PlatformException catch (e) {
print(e);
}
setState(() {
_state = state;
});
print(_state);
}
Future<void> _checkCardState() async {
String cardState;
const primaryAccountIdentifiers = ["a", "b"];
try {
final String result = await platform.invokeMethod(
"checkCardState", primaryAccountIdentifiers);
cardState = result;
} on PlatformException catch (e) {
cardState = "Failed to Invoke: '${e.message}'.";
}
setState(() {
_state = cardState;
});
}
Future<void> _startApplePay() async {
const _cardNetwork = "cn/AMEX";
const _cardHolderName = "pero peric";
const _primaryAccountIdentifier = "a";
const _primaryAccountSuffix = "1234";
const _localizedDescription = "AMEX";
Map<String, dynamic> resultMap = Map();
resultMap['cardNetwork'] = _cardNetwork;
resultMap['cardHolderName'] = _cardHolderName;
resultMap['primaryAccountIdentifier'] = _primaryAccountIdentifier;
resultMap['primaryAccountSuffix'] = _primaryAccountSuffix;
resultMap['localizedDescription'] = _localizedDescription;
platform.invokeMethod("startApplePay", resultMap);
}
#override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
child: Text('Check Card State'),
onPressed: _checkCardState,
),
ElevatedButton(
child: Text('Start Apple Pay'),
onPressed: _startApplePay,
),
Text(_state),
],
),
),
);
}
}
Thanks!

Trying to use Functions in one Page (and Class) to control or use Functions in another in Flutter

Okay. So I'm going to show some code, and I honestly don't know WHY it doesn't work. I just feel like I'm out of my depth, and this is very frustrating.
Now this is NOT the program I'm actually working on, but a super-simple example program that should show the issue I'm having. Please do NOT ask me to put all of these things into or inside a single function or class, as that is NOT an option with my real program, so it wouldn't solve my actual issue.
so in my main.dart I have the following.
import 'package:flutter/cupertino.dart';
import 'dart:async';
import './page2.dart';
void main() => runApp(MyApp());
Page2 myPage = new Page2();
PageState myState = myPage.createState();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool textBool = false;
void changeTest(dynamic function, context) async {
Timer.periodic(Duration (seconds: 2), (Timer t) {
myState.changeText();
counter++;
if (counter >= 10) {
t.cancel();
}
},);
Navigator.push(context, CupertinoPageRoute(builder: (context) => myPage));
}
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(myState.changeText, context),
),
),
);
}
}
and in a second Dart file I have
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import './main.dart';
class Page2 extends StatefulWidget {
#override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
textChanger = false;
setState(() {
});
} else {
print('Change Two');
textChanger = true;
setState(() {
});
}
} else {
firstText = false;
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
}
Now what this program does is switch to the second page, and then stalls, and nothing happens. The timer IS getting called (I can see this through the print-screen function) And I can see that the text SHOULD be changing, as the bools are being altered properly to do so.
Expected functionality: I should be able to call the instance of the second page, and the functions on it, from my main app, and make changes to the text on that second page.
In my real app (Far more complicated, I couldn't possibly parse it down into something that would fit here) I have the same issue. (If I use the hot reload in Flutter the text DOES change in my actual app.)
So as you can see, I'm trying to communicate cross-classes and cross-functions, but either A) I'm not communicating correctly, or B) The communication is with an incorrect instance of the secondary page, and so the setState() call isn't being done on the variant that's being shown? Those are my only guesses.
You shouldn't call the createState manually. For implementing such a thing I prefer to use a stream instead, which is pretty much easy to handle.
timerStream.dart
import 'dart:async';
class TimerStream {
StreamController _streamController;
StreamSink<bool> get timerSink =>
_streamController.sink;
Stream<bool> get timerStream =>
_streamController.stream;
TimerStream() {
_streamController = StreamController<bool>();
}
dispose() {
_streamController?.close();
}
}
main.dart
import 'dart:async';
import 'package:flutter/cupertino.dart';
import './page2.dart';
import './timerStream.dart';
void main() => runApp(MyApp());
TimerStream stream = TimerStream();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool textBool = false;
void changeTest(context) async {
Navigator.push(context, CupertinoPageRoute(builder: (context) => Page2(stream: stream,)));
Timer.periodic(Duration (seconds: 5), (Timer t) {
stream.timerSink.add(true);
});
}
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(context),
),
),
);
}
}
page2.dart
import 'package:flutter/material.dart';
import 'timerStream.dart';
class Page2 extends StatefulWidget {
TimerStream stream;
Page2({this.stream});
#override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
setState(() {
textChanger = false;
});
} else {
print('Change Two');
setState(() {
textChanger = true;
});
}
} else {
firstText = false;
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
#override
void initState() {
super.initState();
widget.stream.timerStream.listen((onData) {
changeText();
});
}
}
Note: If you want, instead of writing true to the stream you can toggle the value and use that in your page2 to change the text.

Load and read data from Json file

I create simple app get data of marker from json file and draw them.
The code below is get data from data.json and add to the list of marker.
I got problem. I can't get data from json file and add it to my marker list. How can I do that?
My main.dart code
class MapSample extends StatefulWidget {
#override
State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
#override
void initState() {
var location = Location();
FutureBuilder(
future:
DefaultAssetBundle.of(context).loadString('assets/data.json'),
builder: (context, snapshot) {
// Decode the JSON
var new_data = json.decode(snapshot.data.toString());
for (var i = 0; i < new_data.length; i++) {
location = Location(
id: new_data[i]['id'],
lat: new_data[i]['x'],
long: new_data[i]['y'],
);
locations.add(location);
//print(location.lat);
}
});
super.initState();
}
}
My data.json
[{
"rownum": 1,
"id": "E3E0D2C5-CB82-4AF3-8D5D-4CD323560F59",
"x": 10.99803453,
"y": 106.65676933,
}, {
"rownum": 2,
"id": "5FFB6736-7D1F-4B40-A397-32EB3128BC30",
"x": 10.99793271,
"y": 106.65666751,
},
I think this is what you are looking for.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(Test());
}
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
Future _future;
List<Location> locations;
Future<String> loadJson() async =>
await rootBundle.loadString('assets/data.json');
#override
void initState() {
_future = loadJson();
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.hasData) {
for (var v in snapshot.data) {
locations.add(Location(
id: v['id'],
lat: v['x'],
long: v['y'],
));
}
return Text(snapshot.data);
} else {
return CircularProgressIndicator();
}
}),
),
);
}
}
class Location {
final String id;
final double lat;
final double long;
Location({this.id, this.lat, this.long});
}
Try this.
You have to add the data.json file in assests.
Then add in to pubspec.yaml file.
assets:
- assets/data.json
Then add this below code.
String jsonData = await DefaultAssetBundle.of(context).loadString("assets/data.json");
final jsonResult = json.decode(jsonData);

Resources