huhx / flutter_oss_aliyun

阿里云oss sdk的flutter版本
MIT License
61 stars 23 forks source link

报错Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>' #52

Closed xaiocaiji7653 closed 7 months ago

xaiocaiji7653 commented 7 months ago

为啥所有的这行代码 await Client().putObject( 都报错Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>' flutter版本3.18.0 dart版本3.3.0 求大佬解答

huhx commented 7 months ago

有可以复现的小 demo 吗

xaiocaiji7653 commented 7 months ago

有可以复现的小 demo 吗 直接用pub仓库给的example都会报错 // ignore: depend_on_referenced_packages import 'package:flutter/foundation.dart'; // ignore: depend_on_referenced_packages import 'package:flutter/material.dart'; import 'package:flutter_appointment_photography/net/http_constant.dart'; import 'package:flutter_oss_aliyun/flutter_oss_aliyun.dart';

// void main() { // runApp( // const MaterialApp( // debugShowCheckedModeBanner: false, // home: HomeScreen(), // ), // ); // }

class HomeScreen extends StatefulWidget { const HomeScreen({super.key});

@override State createState() => _HomeScreenState(); }

class _HomeScreenState extends State { @override void initState() { super.initState(); Client.init( stsUrl: HttpConstant.stsUrl, ossEndpoint: "oss-cn-chengdu.aliyuncs.com", bucketName: "ap-photo-server", ); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Flutter aliyun oss example"), ), body: Container( alignment: Alignment.center, child: Column( children: [ TextButton( onPressed: () async { final bytes = Uint8List.fromList("Hello World".codeUnits); await Client().putObject( bytes, "filename.txt", option: PutRequestOption( onSendProgress: (count, total) { if (kDebugMode) { print("send: count = $count, and total = $total"); } }, onReceiveProgress: (count, total) { if (kDebugMode) { print("receive: count = $count, and total = $total"); } }, override: false, aclModel: AclMode.private, storageType: StorageType.standard, callback: const Callback( callbackUrl: "callbackUrl", callbackBody: "{\"mimeType\":\${mimeType}, \"filepath\":\${object},\"size\":\${size},\"bucket\":\${bucket},\"phone\":\${x:phone}}", callbackVar: {"x:phone": "android"}, calbackBodyType: CalbackBodyType.json, ), ), ); }, child: const Text("Upload object"), ), TextButton( onPressed: () async { await Client().getObject( "filename.txt", onReceiveProgress: (count, total) { debugPrint("received = $count, total = $total"); }, ); }, child: const Text("Get object"), ), TextButton( onPressed: () async { await Client().downloadObject( "filename.txt", "./example/savePath.txt", onReceiveProgress: (count, total) { debugPrint("received = $count, total = $total"); }, ); }, child: const Text("Download object"), ), TextButton( onPressed: () async { await Client().deleteObject("filename.txt"); }, child: const Text("Delete object"), ), TextButton( onPressed: () async { await Client().putObjects( [ AssetEntity( filename: "filename1.txt", bytes: "files1".codeUnits, option: PutRequestOption( onSendProgress: (count, total) { if (kDebugMode) { print("send: count = $count, and total = $total"); } }, onReceiveProgress: (count, total) { if (kDebugMode) { print( "receive: count = $count, and total = $total"); } }, override: true, aclModel: AclMode.inherited, ), ), AssetEntity( filename: "filename2.txt", bytes: "files2".codeUnits), ], ); }, child: const Text("Batch upload object"), ), TextButton( onPressed: () async { await Client() .deleteObjects(["filename1.txt", "filename2.txt"]); }, child: const Text("Batch delete object"), ), ], ), ), ); } }

xaiocaiji7653 commented 7 months ago

有可以复现的小 demo 吗

image

huhx commented 7 months ago
image

 test("test the put test in Client", () async {
    final String string = "Hello World";

    final Response<dynamic> resp = await Client().putObject(
      Uint8List.fromList(utf8.encode(string)),
      "test-test.txt",
      option: PutRequestOption(
        onSendProgress: (count, total) {
          print("send: count = $count, and total = $total");
        },
        onReceiveProgress: (count, total) {
          print("receive: count = $count, and total = $total");
        },
        override: true,
        aclModel: AclMode.publicRead,
        storageType: StorageType.ia,
        callback: Callback(
          callbackUrl: callbackUrl,
          callbackBody:
              "{\"mimeType\":\${mimeType}, \"filepath\":\${object},\"size\":\${size},\"bucket\":\${bucket},\"phone\":\${x:phone}}",
          callbackVar: {"x:phone": "android"},
          calbackBodyType: CalbackBodyType.json,
        ),
      ),
    );
xaiocaiji7653 commented 7 months ago

还是不行,但是我改了client.dart文件里面的代码成功了,但是访问oss报错403 client image

huhx commented 7 months ago

如果是提供了 stsUrl,那么需要返回的json结构如下

{
  "AccessKeyId": "AccessKeyId",
  "AccessKeySecret": "AccessKeySecret",
  "SecurityToken": "SecurityToken",
  "Expiration": "2022-03-22T11:33:06Z"
}

这是我后端返回的例子:

image
xaiocaiji7653 commented 7 months ago

如果是提供了 stsUrl,那么需要返回的json结构如下

{
  "AccessKeyId": "AccessKeyId",
  "AccessKeySecret": "AccessKeySecret",
  "SecurityToken": "SecurityToken",
  "Expiration": "2022-03-22T11:33:06Z"
}

这是我后端返回的例子: image

这是我的,顺序不一样有影响吗? image

huhx commented 7 months ago

结构是没问题,你是说文件上传成功了(可以在 aliyun 网页上面检查),但是访问文件报403?

xaiocaiji7653 commented 7 months ago

文件没上传成功,只是从后端成功获取了sts凭证,但是用sts凭证上传文件的时候报403了,我怀疑是阿里云角色权限问题,但是重新创建了还是403

xaiocaiji7653 commented 7 months ago

结构是没问题,你是说文件上传成功了(可以在 aliyun 网页上面检查),但是访问文件报403?

文件没上传成功,只是从后端成功获取了sts凭证,但是用sts凭证上传文件的时候报403了,我怀疑是阿里云角色权限问题,但是重新创建了还是403

xaiocaiji7653 commented 7 months ago

成功了,就是我权限没设置好,感谢大佬