在操场上运行的 Graphql_flutter 突变不适用于运行设备/模拟器

问题描述

在我的项目开发过程中,我将 Flutter 与 graphql 一起使用,出于测试目的,我在操场上尝试了突变并通过了测试,但是在设备和模拟器上收到了 5xx 的错误响应,我知道这是“服务器端”错误,但经过测试来自我们网页的相同突变,它也有效。 除了颤振,我还使用以下软件包:

  • 等同:^1.2.5
  • gql:^0.12.4
  • graphql:^4.0.0
  • graphql_Flutter:^4.0.1
  • json_annotation: ^3.1.1
  • 元:^1.3.0
  • 阿尔忒弥斯:^6.18.4
  • build_runner:^1.11.1
  • json_serializable:^3.5.1

到目前为止,在这个项目中,我使用这个文件语法成功运行了近 10 个突变:

  • 我的项目/
    • graphql/
      • 查询/
        • register.graphql -> 运行良好
        • createOffer.graphql -> 出现 500 错误
      • schema.graphql
    • 库/

注册.graphql

mutation signUp(
    $company_name:String!,$email: String!,$firstname: String!,$lastname: String!,$phone: String!,$tin_ein_number: String!,) {
    createShipperUser(
        company_name: $company_name,email: $email,firstname: $firstname,lastname: $lastname,phone: $phone,tin_ein_number: $tin_ein_number,) {
        id
    }
}

注册.dart

Widget buildFormBody(BuildContext context) {
    return Mutation(
      options: Mutationoptions(
        document: SignUpMutation().document,onCompleted: (dynamic resultData) {
          if (resultData != null) {
            onRegistered();
          }
        },if (e.linkException != null) {
            showSnackbar(context,'Something went wrong,please check your network connection and try again.');
            return;
        }
        final validationErrors = findValidationErrors(
            e.graphqlErrors,[
              'firstname','lastname','email','phone','tin_ein_number','company_name',],);
          if (validationErrors.isNotEmpty) {
            setState(() {
              firstnameError = validationErrors['firstname'];
              surnameError = validationErrors['lastname'];
              emailError = validationErrors['email'];
              phoneError = validationErrors['phone'];
              if (isTin) {
                einError = null;
                tinError = validationErrors['tin_ein_number'];
              } else {
                einError = validationErrors['tin_ein_number'];
                tinError = null;
              }
              companyError = validationErrors['company_name'];
            });
            //Todo text
            showSnackbar(context,'Please check entered fields');
          } else if (e.graphqlErrors.isNotEmpty) {
            showSnackbar(
                context,e.graphqlErrors[0].message ?? 'Something went wrong');
          } else {
            showSnackbar(context,'Something went wrong');
          }
          builder: (runMutation,result) {
           isLoading = result.isLoading;
           return Form( 
             ElevatedButton(
               onpressed: () => onSubmitTap(runMutation),child: Text(
                              'Submit',style: TextStyle(
                                  fontSize: 16,fontWeight: FontWeight.w700),),)         
           );
        
  void onSubmitTap(RunMutation runMutation) {
    hideKeyboard();
    if (isLoading) {
      return;
    }

    if (formKey.currentState.validate()) {
      formKey.currentState.save();

      setState(() {
        savedPhone = getPhoneMask(savedPhone);
      });

      runMutation(SignUpArguments(
        company_name: savedCompany,email: savedEmail,phone: savedPhone,tin_ein_number: isTin ? 'tin_$savedTin' : 'ein_$savedEin',firstname: savedFirstname,lastname: savedSurname,).toJson());
    }
  }

以下是出现 500 错误的突变。

createOffer.graphql

Mutation(
                      options: Mutationoptions(
                        document: CreateShipmentMutation().document,errorPolicy: ErrorPolicy.all,update: (GraphQLDataProxy cache,QueryResult result) {
                          if (result.hasException) {
                            print(result.exception);
                          }
                        },onCompleted: (dynamic resultData) {
                          if (resultData != null) {
                            print('completed');
                            print(resultData);
                            // onCreated();
                          }
                        },onError: (e) {
                          if (e.linkException != null) {
                            showSnackbar(context,please check your network connection and try again.');
                            return;
                          }

                          if (e.graphqlErrors.isNotEmpty) {
                            debugPrint(e.graphqlErrors.toString(),wrapWidth: 1024);
                          } else {
                            showSnackbar(context,'Something went wrong');
                          }
                        },builder: (runMutation,result) {
                        isLoading = result.isLoading;
                        return Card(
                          child: ElevatedButton(
                                    onpressed: () => onReviewTap(runMutation),style: ElevatedButton.styleFrom(
                                        padding:
                                            EdgeInsets.symmetric(vertical: 14)),child: AnimatedSwitcher(
                                      duration: Duration(milliseconds: 150),child: result.isLoading
                                          ? Theme(
                                              data: Theme.of(context).copyWith(
                                                  accentColor: Colors.white),child:
                                                  const ProgressIndicatorSmall(),)
                                          : Text(
                                              'Review Shipment',style: TextStyle(
                                                  fontSize: 16,);

void onReviewTap(RunMutation runMutation) {
    final acces = accessories
        .map((accessory) {
          if (accessory.isChecked) {
            return accessory.enumType;
          }
        })
        .where((element) => element != null)
        .toList();
    final stops = isMultipleStops ? items : p2pitems;

    hideKeyboard();
    if (isLoading) {
      return;
    }

    runMutation(CreateShipmentArguments(
      input: OfferInput(
        openPrice: 30,shipment: CreateShipmentInput(
          requestedTruckTypes: [
            TruckTypesEnum.dryVan,accessorials: [
            AccessorialsEnum.twicrequired,AccessorialsEnum.ppe,trailer: TrailerInput(
            temperatureMax: 0,temperatureMin: 0,temperatureUnit: TemperatureUnitsEnum.f,items: [
            ItemInput(
              description: "Items description",weight: WeightInput(
                weight: 100,weightUnit: WeightUnitTypesEnum.lb,units: UnitInput(
                unitCount: 0,unitType: ItemunitTypesEnum.units,handlingPiece: HandlingPieceInput(
                pieceCount: 0,pieceType: ItemPieceTypesEnum.pallets,shortName: "Dem23",loadDescription: "adhjahsdhajsdj",routedistanceMiles: 0.0,routeDurationMinutes: 0,stops: [
            CreateStopInput(
                appointmentType: AppointmentTypesEnum.alreadyMade,startTime: "2021-05-03T00:00:00+02:00",type: StopTypesEnum.pickup,loadingType: LoadingTypesEnum.live,locationInput: LocationInput(
                  locationName: "HOUSTON",coordinates:
                      CoordinatesInput(lat: 29.608774,lng: -95.516164),address: AddressInput(
                      full:
                          "14810 Fairway Pines Dr,Missouri City,TX 77489,USA",city: "Missouri City",state: "TX",street: "Fairway Pines Drive",streetNumber: 14810),operationalContact: ContactInput(
                      contactName: "mr contact",email: "[email protected]",phoneNumber: "862615986",notes: "notes lorem ipsum"),schedulingContact: ContactInput(
                      contactName: "mr contact",)),CreateStopInput(
              appointmentType: AppointmentTypesEnum.toBeMade,startTime: "2021-05-14T05:13:30+00:00",endTime: "2021-04-27T17:35:00+00:00",type: StopTypesEnum.dropoff,locationInput: LocationInput(
                locationName: "COSTCO WHO,WEBSTER,TX,coordinates: CoordinatesInput(lat: 29.533604,lng: -95.136843),address: AddressInput(
                  full: "1310 Jasmine St,Webster,TX 77598,city: "Webster",street: "Jasmine Street",streetNumber: 1310,operationalContact: ContactInput(
                    contactName: "mr contact",email: "[email protected]",schedulingContact: ContactInput(
                    contactName: "mr contact",).toJson());

以下是 createOffer 在 Playground 上的硬编码:

mutation CreateShipment (
  $input: OfferInput!
) {
  createOffer(input: $input){
    uuid
    shipper_id
  }
}
#variables
{
  "input": {
    "open_price": 30,"shipment": {
      "requested_truck_types": [
        "DRY_VAN"   
      ],"accessorials": [
        "TWIC_required","SHIPPER_REQUIRES_MASK_gloveS","PPE"
      ],"items": [
        {
          "description": "Items description","handling_piece": {
            "piece_type": "PALLETS","piece_count": 0
          },"units": {
            "unit_type": "UNITS","unit_count": 0
          },"weight": {
            "weight": 100,"weight_unit": "LB"
          }
        }
      ],"trailer": {
        "temperature_max": 0,"temperature_min": 0,"temperature_unit": "F"
      },"short_name": "Dem","load_description": "load descriotajj adaksdjad","route_distance_miles": 0.0,"route_duration_minutes": 0,"stops": [
        {
          "appointment_type": "ALREADY_MADE","start_time": "2021-05-03T00:00:00+02:00","type": "PICKUP","loading_type": "LIVE","location_input": {
            "location_name": "HOUSTON","coordinates": {
              "lat": 29.608774,"lng": -95.516164
            },"address": {
              "full": "14810 Fairway Pines Dr,"city": "Missouri City","state": "TX","street": "Fairway Pines Drive","street_number" :14810
            },"operational_contact": {
              "contact_name" : "mr contact","email" : "[email protected]","phone_number" : "862615986","notes" : "notes lorem ipsum"
            },"scheduling_contact": {
              "contact_name" : "mr contact","notes" : "notes lorem ipsum"
            }
          }
        },{
          "appointment_type": "TO_BE_MADE","start_time": "2021-05-14T05:13:30+00:00","end_time": "2021-04-27T17:35:00+00:00","type": "DROPOFF","location_input": {
            "location_name": "COSTCO WHO,"coordinates": {
              "lat": 29.533604,"lng": -95.136843
            },"address": {
              "full": "1310 Jasmine St,"city": "Webster","street": "Jasmine Street","street_number" :1310
            },"email" : "[email protected]","notes" : "notes lorem ipsum"
            }
          }
        }
      ]
    }
  }
}

和响应

{
  "data": {
    "createOffer": {
      "uuid": "933eee0a-8x82-46d6-xxx-018xxxxxxx40","shipper_id": "3"
    }
  },"extensions": {
    "lighthouse_subscriptions": {
      "version": 1,"channel": null,"channels": []
    }
  }
}

为了检查是否工作 graphql 验证,我在开始时间/结束时间的日期时间犯了错误并得到这个:

{
  "errors": [
    {
      "message": "Variable \"$input\" got invalid value {\"open_price\":30,\"shipment\":{\"requested_truck_types\":[\"DRY_VAN\"],\"accessorials\":[\"TWIC_required\",\"SHIPPER_REQUIRES_MASK_gloveS\",\"PPE\"],\"items\":[{\"description\":\"Items description\",\"handling_piece\":{\"piece_type\":\"PALLETS\",\"piece_count\":0},\"units\":{\"unit_type\":\"UNITS\",\"unit_count\":0},\"weight\":{\"weight\":100,\"weight_unit\":\"LB\"}}],\"trailer\":{\"temperature_max\":0,\"temperature_min\":0,\"temperature_unit\":\"F\"},\"short_name\":\"Dem\",\"load_description\":\"load descriotajj adaksdjad\",\"route_distance_miles\":0,\"route_duration_minutes\":0,\"stops\":[{\"appointment_type\":\"ALREADY_MADE\",\"start_time\":\"2021-05-03T00:00:00\",\"type\":\"PICKUP\",\"loading_type\":\"LIVE\",\"location_input\":{\"location_name\":\"HOUSTON\",\"coordinates\":{\"lat\":29.608774,\"lng\":-95.516164},\"address\":{\"place_id\":\"EjQxNDgxMCBGYWlyd2F5IFBpbmVzIERyLCBNaXNzb3VyaSBDaXR5LCBUWCA3NzQ4OSwgVVNB\",\"full\":\"14810 Fairway Pines Dr,USA\",\"city\":\"Missouri City\",\"state\":\"TX\",\"street\":\"Fairway Pines Drive\",\"street_number\":14810},\"operational_contact\":{\"contact_name\":\"mr contact\",\"email\":\"[email protected]\",\"phone_number\":\"862615986\",\"notes\":\"notes lorem ipsum\"},\"scheduling_contact\":{\"contact_name\":\"mr contact\",\"notes\":\"notes lorem ipsum\"}}},{\"appointment_type\":\"TO_BE_MADE\",\"start_time\":\"2021-05-14T05:13:30+00:00\",\"end_time\":\"2021-04-27T17:35:00+00:00\",\"type\":\"DROPOFF\",\"location_input\":{\"location_name\":\"COSTCO WHO,\"coordinates\":{\"lat\":29.533604,\"lng\":-95.136843},\"address\":{\"full\":\"1310 Jasmine St,\"city\":\"Webster\",\"street\":\"Jasmine Street\",\"street_number\":1310},\"notes\":\"notes lorem ipsum\"}}}]}}; Expected type DateTimeTz at value.shipment.stops[0].start_time; \"Data missing\"","extensions": {
        "category": "graphql"
      },"locations": [
        {
          "line": 1,"column": 25
        }
      ]
    }
  ],"channels": []
    }
  }
}

这意味着我发送的所有字段都是正确的,我想。也许请求的字段类型正在接受我的有效输入类型,但在工作/解析它们时导致错误,我不知道,我为此苦苦挣扎了将近一周,正如您所看到的,两个硬代码(颤振/操场)是相同的.我的文本字段和其他输入已准备就绪,但我无法首先运行硬编码:/顺便说一句,这不是过期令牌,因为我收到了未经授权的操作错误

解决方法

终于可以解决这个问题了。解析来自我这边的数据时,后端出现问题。这是数据流:

  • 用户输入数据
  • 变异前,flutter解析数据和graphql_flutter变异
  • 然后,如果一切正常,后端(在我们的例子中是 php)进行字段验证,然后,如果没有,则向客户端发送验证错误。
  • 毕竟,服务器开始在 db 上存储数据(这里是关键点)

我的问题发生在最后阶段,不必要的模型属性被发送为空,我们通过阅读 laravel.log 中的日志来了解这一点,因此删除该字段并迁移数据库,最后下载并使用“新”schema.graphql 来自游乐场解决了这个问题。我希望这会在以后有所帮助:)