“ _CastError(用于空值的空检查运算符)” Flutter

" _CastError (Null check operator used on a null value) " Flutter

当与我的启动规范的函数交互时,return 给我这个错误:“_CastError(空检查运算符用于空值)”

错误代码:

 initSpecsTechs() async {
    specs = await APIBike()
        .getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
    initBluetoothConnection();
    initSliderAutomaticExtinctionValue();
    initSliderAutomaticLockingValue();
    initBackLightMode();
  }

我的页面设置的完整代码(第一行包含错误代码):

import 'package:myapp/api_bike.dart';
import 'package:myapp/api_user.dart';
import 'package:myapp/ux_components.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'blur_filter.dart';

class SettingsPage extends StatefulWidget {
  @override
  SettingsPageState createState() => SettingsPageState();

  SettingsPage({required Key key}) : super(key: key);
}

class SettingsPageState extends State<SettingsPage>
    with AutomaticKeepAliveClientMixin<SettingsPage> {
  User? _user;
  List<Bike> _bikes = [];
  Bike? favoriteBike;
  Specs? specs;
  bool connectedByBluetooth = true;
  double _currentSliderAutomaticExtinctionValue = 0;
  double _currentSliderAutomaticLockingValue = 0;
  bool theftAlertIsActive = true;
  bool batteryAlertIsActive = true;
  bool maintainAlertIsActive = true;
  bool constantBackLight = true;
  double spaceAfterSmallTitle = 15;
  double spaceAfterWidget = 20;

  //INIT FUNCTIONS
  init() async {
    await initUser();
    await initBikes();
    await initFavoriteBike();
    await initSpecsTechs();
  }

  Future initUser() async {
    final storage = new FlutterSecureStorage();
    String mail = await storage.read(key: "mail") ?? "";
    String password = await storage.read(key: "password") ?? "";
    UserResponse userResponse = await APIUser()
        .login(mail, password); //L'identifiant peut être le username ou le mail
    User? user = userResponse.user;
    if (user != null) {
      setState(() {
        _user = user;
      });
    }
    return user;
  }

  initBikes() async {
    if (_user != null) {
      List<Bike> bikes = await APIBike().getAllUserBikes(jwt: _user!.jwt);
      setState(() {
        _bikes = bikes;
      });
    } else {
      print("could not get the bikes call the user is null");
    }
  }

  initFavoriteBike() async {
    if (_bikes.length == 0) {
      favoriteBike = null;
    } else if (_bikes.length == 1) {
      setState(() {
        favoriteBike = _bikes.first;
      });
    } else {
      Bike? favBike = await APIBike().getFavoriteBike(jwt: _user!.jwt);
      if (favBike != null) {
        setState(() {
          favoriteBike = favBike;
        });
      } else {
        print("PROBLEM : FAVORITE BIKE IS NULL");
      }
    }
  }

  initSpecsTechs() async {
    specs = await APIBike()
        .getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
    initBluetoothConnection();
    initSliderAutomaticExtinctionValue();
    initSliderAutomaticLockingValue();
    initBackLightMode();
  }

  initBackLightMode() {
    if (specs != null) {
      bool constantBackLightValue = false;
      if (specs!.rearLight == "fixed") {
        constantBackLightValue = true;
      }
      setState(() {
        constantBackLight = constantBackLightValue;
      });
    } else {
      print("Fake value used for initBackLightMode");
    }
  }

  initTheftAlertIsActive() {
    if (specs != null) {
      setState(() {
        theftAlertIsActive = specs!.theftAlarm;
      });
    } else {
      print("Fake value used for initStealAlertIsActive");
    }
  }

  initBatteryAlertIsActive() {
    if (specs != null) {
      setState(() {
        batteryAlertIsActive = specs!.batteryAlarm;
      });
    } else {
      print("Fake value used for initBatteryAlertIsActive");
    }
  }

  initMaintenanceAlertIsActive() {
    if (specs != null) {
      setState(() {
        maintainAlertIsActive = specs!.maintenanceAlarm;
      });
    } else {
      print("Fake value used for initMaintenanceAlertIsActive");
    }
  }

  initBluetoothConnection() {
    //If this value is false then the page is all grey with nothing active
    setState(() {
      connectedByBluetooth = true;
    });
  }

  initSliderAutomaticExtinctionValue() {
    if (specs != null) {
      double sliderValue = 0;
      if (specs!.automaticSwitchOff == 0) {
        sliderValue = 4;
      } else if (specs!.automaticSwitchOff == 5) {
        sliderValue = 0;
      } else if (specs!.automaticSwitchOff == 10) {
        sliderValue = 1;
      } else if (specs!.automaticSwitchOff == 15) {
        sliderValue = 2;
      } else if (specs!.automaticSwitchOff == 20) {
        sliderValue = 3;
      } else {
        //If there is a problem (it is not suppose to happen, we set it to never)
        sliderValue = 0;
      }
      setState(() {
        _currentSliderAutomaticExtinctionValue = sliderValue;
      });
    } else {
      print("Fake value used for initSliderAutomaticExtinctionValue");
    }
  }

  initSliderAutomaticLockingValue() {
    if (specs != null) {
      double sliderValue = 0;
      if (specs!.automaticLocking == 0) {
        sliderValue = 4;
      } else if (specs!.automaticLocking == 1) {
        sliderValue = 0;
      } else if (specs!.automaticLocking == 3) {
        sliderValue = 1;
      } else if (specs!.automaticLocking == 5) {
        sliderValue = 2;
      } else if (specs!.automaticLocking == 10) {
        sliderValue = 3;
      } else {
        //If there is a problem (it is not suppose to happen, we set it to never)
        sliderValue = 0;
      }
      setState(() {
        _currentSliderAutomaticLockingValue = sliderValue;
      });
    } else {
      print("Fake value used for initSliderAutomaticLockingValue");
    }
  }

  @override
  void initState() {
    super.initState();
    init();
  }

  //UPDATE FUNCTIONS

  updateRearLightValue(String newValue) async {
    //TODO change the value on the bike by BLE
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "rear_light",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Rear light value updated successfully");
    } else {
      print("Error: rear light value didn't update correctly");
    }
    return operationSucceed;
  }

  updateAutomaticShutDownValue(double sliderValue) async {
    //TODO change the value on the bike by BLE
    int newValue = 0; // is also the value for never
    if (sliderValue == 0) {
      newValue = 5;
    } else if (sliderValue == 1) {
      newValue = 10;
    } else if (sliderValue == 2) {
      newValue = 15;
    } else if (sliderValue == 3) {
      newValue = 20;
    } //else the new value is 0 which is never
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "automatic_switch_off",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Automatic switch off value updated successfully");
    } else {
      print("Error: Automatic switch off value didn't update correctly");
    }
    return operationSucceed;
  }

  updateAutomaticLockingValue(double sliderValue) async {
    //TODO change the value on the bike by BLE
    int newValue = 0; // is also the value for never
    if (sliderValue == 0) {
      newValue = 1;
    } else if (sliderValue == 1) {
      newValue = 3;
    } else if (sliderValue == 2) {
      newValue = 5;
    } else if (sliderValue == 3) {
      newValue = 10;
    } //else the new value is 0 which is never
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "automatic_locking",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Automatic locking value updated successfully");
    } else {
      print("Error: Automatic locking value didn't update correctly");
    }
    return operationSucceed;
  }

  updateTheftAlertIsActive(bool newValue) async {
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "theft_alarm",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Theft alert value updated successfully");
    } else {
      print("Error: theft alert value didn't update correctly");
    }
    return operationSucceed;
  }

  updateBatteryAlertIsActive(bool newValue) async {
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "battery_alarm",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Battery alert value updated successfully");
    } else {
      print("Error: battery alert value didn't update correctly");
    }
    return operationSucceed;
  }

  updateMaintenanceAlertIsActive(bool newValue) async {
    bool operationSucceed = await APIBike().updateSpecsTechs(
        jwt: _user!.jwt,
        bikeId: favoriteBike!.id,
        specToUpdate: "maintenance_alarm",
        newSpecValue: newValue);
    if (operationSucceed) {
      print("Maintenance alert value updated successfully");
    } else {
      print("Error: maintenance alert value didn't update correctly");
    }
    return operationSucceed;
  }
 /.../
 

最后是我的 api 用户:

import 'dart:collection';

import 'package:myapp/api_bike.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class ResponseWithError {
  final bool result;
  final String error;

  ResponseWithError(this.result, this.error);
}

class APIUser {
  //For dev
  final String serverAddress =
      "https://myadress.com/";

  //TODO For production:
  //final String serverAddress = "https://prodadress.com";

  Future<ResponseWithError> createUser(
      String firstname, String lastname, String email, String password) async {
    var body =
        """{"username": "$firstname $lastname", "firstname": "$firstname", "lastname": "$lastname",  "email": "$email", "password": "$password"}""";

    var client = new http.Client();

    var response = await client.post(
        Uri.parse("$serverAddress/auth/local/register"),
        body: body,
        headers: {"Content-Type": 'application/json'});
    if (response.statusCode == 200) {
      print("USER CREATED");
      print(response.body);
      return ResponseWithError(true, "none");
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      var responseBody = jsonDecode(response.body);
      if (responseBody["message"][0]["messages"][0]["id"] != null) {
        String errorMessageId = responseBody["message"][0]["messages"][0]["id"];
        if (errorMessageId == "Auth.form.error.email.format") {
          return ResponseWithError(false, "email format");
        }
      }
      return ResponseWithError(false, "not known");
    }
  }

  Future<UserResponse> login(String identifier, String password) async {
    var body = """{"identifier": "$identifier", "password": "$password"}""";

    var client = new http.Client();

    var response = await client.post(Uri.parse("$serverAddress/auth/local"),
        body: body, headers: {"Content-Type": 'application/json'});
    if (response.statusCode == 200) {
      //print("USER LOGGED IN");
      final parsed = jsonDecode(response.body);
      User user = User.fromJson(parsed);
      UserResponse userResponse = UserResponse(user, true);
      return userResponse;
    } else {
      //print("Error " + response.statusCode.toString());
      //print("Response Body");
      //print(response.body);
      var responseBody = jsonDecode(response.body);
      if (responseBody["message"][0]["messages"][0]["id"] != null) {
        String errorMessageId = responseBody["message"][0]["messages"][0]["id"];
        if (errorMessageId == "Auth.form.error.confirmed") {
          print("User not confirmed");
          UserResponse userResponse = UserResponse(null, false);
          return userResponse;
        } else /*if(errorMessageId == "Auth.form.error.invalid")*/ {
          print("email or password incorrect");
          UserResponse userResponse = UserResponse(null, true);
          return userResponse;
        }
      }
      //Should not happen, but just in case
      UserResponse userResponse = UserResponse(null, true);
      return userResponse;
    }
  }

  Future<bool> updateToken(String jwt, String notificationId) async {
    var body = """{"notification_id": "$notificationId"}""";

    var client = new http.Client();

    var response = await client.put(Uri.parse("$serverAddress/users/token"),
        body: body,
        headers: {
          "Content-Type": 'application/json',
          'Authorization': 'Bearer $jwt'
        });

    if (response.statusCode == 200) {
      print("NOTIFICATION TOKEN UPDATED");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> updateEmail(String jwt, String newEmail) async {
    var confirmed = false;
    var body = """{"email": "$newEmail", "confirmed": "$confirmed"}""";

    var client = new http.Client();

    var response = await client.put(Uri.parse("$serverAddress/users/me"),
        body: body,
        headers: {
          "Content-Type": 'application/json',
          'Authorization': 'Bearer $jwt'
        });

    if (response.statusCode == 200) {
      print("EMAIL UPDATED");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> updateNames(
      String jwt, String newFirstname, String newLastName) async {
    var body =
        """{"username": "$newFirstname $newLastName", "firstname": "$newFirstname", "lastname": "$newLastName"}""";

    var client = new http.Client();

    var response = await client.put(Uri.parse("$serverAddress/users/me"),
        body: body,
        headers: {
          "Content-Type": 'application/json',
          'Authorization': 'Bearer $jwt'
        });

    if (response.statusCode == 200) {
      print("NAMES UPDATED");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> updatePassword(String jwt, String newPassword) async {
    var body = """{"password": "$newPassword"}""";

    var client = new http.Client();

    var response = await client.put(Uri.parse("$serverAddress/users/me"),
        body: body,
        headers: {
          "Content-Type": 'application/json',
          'Authorization': 'Bearer $jwt'
        });

    if (response.statusCode == 200) {
      print("PASSWORD UPDATED");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> sendConfirmationCode(String email) async {
    var body = """{"email": "$email"}""";

    var client = new http.Client();

    var response = await client.post(
        Uri.parse("$serverAddress/auth/send-email-confirmation"),
        body: body,
        headers: {"Content-Type": 'application/json'});

    if (response.statusCode == 200) {
      print("EMAIL SENT to $email");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> verifyEmail(String email, String code) async {
    var body = """{"email": "$email", "confirmation": "$code"}""";

    var client = new http.Client();

    var response = await client.put(
        Uri.parse("$serverAddress/auth/email-confirmation"),
        body: body,
        headers: {"Content-Type": 'application/json'});

    if (response.statusCode == 200) {
      print("EMAIL VERIFIED");
      return true;
    } else {
      print("Error " + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }

  Future<bool> passwordForgotten({required String email}) async {
    var body = """{"email": "$email"}""";

    var client = new http.Client();

    var response = await client.post(
        Uri.parse("$serverAddress/auth/forgot-password"),
        body: body,
        headers: {"Content-Type": 'application/json'});

    if (response.statusCode == 200) {
      return true;
    } else {
      print("Error passwordForgotten :" + response.statusCode.toString());
      print("Response Body");
      print(response.body);
      return false;
    }
  }
}

class UserResponse {
  User? user;
  bool userConfirmed;

  UserResponse(this.user, this.userConfirmed);
}

class User {
  final int id;
  final String jwt;
  final String username;
  final String firstname;
  final String lastname;
  final String email;
  final String provider;
  final bool confirmed;
  final bool? blocked;
  final String? notificationId;
  final String createdAt;
  final String updatedAt;
  final List<int>?
      bikesId; //Here we just save the ids of the bikes linked to the user
  final Subscription? subscription;
  final Role role;

  User({
    required this.id,
    required this.jwt,
    required this.username,
    required this.firstname,
    required this.lastname,
    required this.email,
    required this.provider,
    required this.confirmed,
    required this.blocked,
    required this.notificationId,
    required this.createdAt,
    required this.updatedAt,
    required this.bikesId,
    required this.subscription,
    required this.role,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    if (json['user']['subscription'] != null) {
      return User(
          id: json['user']['id'] as int,
          jwt: json['jwt'] as String,
          username: json['user']['username'] as String,
          firstname: json['user']['firstname'] as String,
          lastname: json['user']['lastname'] as String,
          email: json['user']['email'] as String,
          provider: json['user']['provider'] as String,
          confirmed: json['user']['confirmed'] as bool,
          blocked: json['user']['blocked'] as bool?,
          notificationId: json['user']['notification_id'] as String?,
          createdAt: json['user']['created_at'] as String,
          updatedAt: json['user']['updated_at'] as String,
          bikesId: createBikesIdList(json['user']['bikes_id']),
          subscription: Subscription(
              id: json['user']['subscription']['id'],
              name: json['user']['subscription']['name'],
              createdAt: json['user']['subscription']['created_at'],
              updatedAt: json['user']['subscription']['updated_at']),
          role: Role(
            id: json['user']['role']['id'],
            name: json['user']['role']['name'],
            description: json['user']['role']['description'],
            type: json['user']['role']['type'],
          ));
    } else {
      return User(
          id: json['user']['id'] as int,
          jwt: json['jwt'] as String,
          username: json['user']['username'] as String,
          firstname: json['user']['firstname'] as String,
          lastname: json['user']['lastname'] as String,
          email: json['user']['email'] as String,
          provider: json['user']['provider'] as String,
          confirmed: json['user']['confirmed'] as bool,
          blocked: json['user']['blocked'] as bool?,
          notificationId: json['user']['notification_id'] as String?,
          createdAt: json['user']['created_at'] as String,
          updatedAt: json['user']['updated_at'] as String,
          bikesId: createBikesIdList(json['user']['bikes_id']),
          subscription: null,
          role: Role(
            id: json['user']['role']['id'],
            name: json['user']['role']['name'],
            description: json['user']['role']['description'],
            type: json['user']['role']['type'],
          ));
    }
  }

  describe() {
    print("id : $id\njwt : $jwt");
  }
}

class Role {
  final int id;
  final String name;
  final String description;
  final String type;

  Role({
    required this.id,
    required this.name,
    required this.description,
    required this.type,
  });
}

class Subscription {
  final int id;
  final String name;
  final String createdAt;
  final String updatedAt;

  Subscription(
      {required this.id,
      required this.name,
      required this.createdAt,
      required this.updatedAt});
}

你能这样试试吗?我认为 user 或 favoriteBike 为空。您需要进行空检查。

 initSpecsTechs() async {
    if(_user != null && favoriteBike != null){
     specs = await APIBike()
            .getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
        initBluetoothConnection();
        initSliderAutomaticExtinctionValue();
        initSliderAutomaticLockingValue();
        initBackLightMode();
     } 
    }
  initSpecsTechs() async {
    specs = await APIBike()
        .getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
    initBluetoothConnection();
    initSliderAutomaticExtinctionValue();
    initSliderAutomaticLockingValue();
    initBackLightMode();
  }

“!”运算符导致异常而不是使用“?”像这样

规格=等待APIBike() .getSpecsTechs(jwt: _user?.jwt??'', bikeId: favoriteBike?.id??'');