【问题标题】:Appwrite for Flutter Create Session Throwing Concurrent Modification ExceptionAppwrite for Flutter 创建会话抛出并发修改异常
【发布时间】:2022-07-09 06:23:34
【问题描述】:

我正在尝试在 Flutter 中使用 Appwrite 实现一个基本的登录功能,无论我采用什么方式,我都会不断收到并发修改错误,而不是未来通过帐户会话正确返回,但它不一致且看似随机如果失败与否。但是,我无法确定为什么会发生这种情况,因为我不会以任何方式使用将来返回的数据。我只是触发回调以导航到新页面。任何帮助弄清楚是否是我都将不胜感激。

预期的结果是,在按下登录按钮时,Appwrite 未来会在方法调用中运行,然后一旦完成,应用程序将触发移动到仪表板。它此时不会保存、使用或以任何方式访问此信息。这确实会发生,当它发生时,没有问题。但它需要 100% 的时间发生,而不是像现在这样随机发生。

这是随机捕获并抛出的错误:

flutter: AppwriteException: null, Concurrent modification during iteration: Instance(length:2) of '_GrowableList'. (0)

这也不是唯一引发此错误的 Appwrite 方法,但我的部分故障排除是获取我正在构建的登录并将其归结为绝对最低限度,如下面的代码所示.然而,这种情况仍在继续发生。我什至几乎完全使用了他们的文档示例here 下列出的代码。

我已经将我的 Flutter 版本和 Appwrite 包版本都更新到了最新版本,并在他们的 Github page 上查看了他们的错误报告,认为这是他们的包中的东西,但这在我的 Appwrite 实现中无处不在.我认为这将是一个巨大的问题,如果这不仅仅是我做错了什么或误解,而且在项目页面上的近 300 个未解决的问题中一次也没有出现。我在这里也找不到与此问题特别相关的任何内容。有关于并发修改错误以及它们如何发生、如何避免它们等的常见信息。但我根本不会访问、使用或修改这里的任何数据。

据我所知,这不应该是异步调用的问题,因为此时我实际上并没有在代码库中对返回的数据做任何事情,以后也没有。我不以任何形状或形式存储它,因此我还没有做到那么远。它只是等待future完成,然后触发Navigation to the dashboard page。

下面是有问题的登录方法:

    // Login to Appwrite Backend
login(BuildContext context,String username, String password) {
  Client client = Client();
  Account account = Account(client);

  client
      .setEndpoint('https://jeff.vmsimple.com/v1') // Your API Endpoint
      .setProject('jeffs-timekeeper'); // Your project ID

  Future result = account.createSession(
    email: username,
    password: password,
  );

  result.then((response) {
    print(response);

    // Navigator.push(
    // context,
    //   MaterialPageRoute(
    //       builder: (context) =>
    //       const DashboardScreen(title: 'Dashboard')),
    // );
    Navigator.popAndPushNamed(context, '/dashboardScreen');

    // return response;
  }).catchError((error) {
    print(error);
    // return null;
  });
}

下面是flutter构建函数,它在按下登录时使用它进行回调。这是一个无状态的小部件,除了表单字段之外没有其他移动部件,它们被传递到上面的登录方法中。

Widget build(BuildContext context) {
  // Check If logged in, and redirect to Dashboard if so
  // checkLogin(context);

  TextEditingController _emailController = TextEditingController();
  TextEditingController _passwordController = TextEditingController();

  return Scaffold(
    appBar: AppBar(
      title: Text(title),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'Login',
            style: Theme.of(context).textTheme.headline4,
          ),
          Container(
            margin: const EdgeInsets.fromLTRB(25, 25, 25, 12.5),
            child: TextField(
              controller: _emailController,
              obscureText: false,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Username',
              ),
            ),
          ),
          Container(
            margin: const EdgeInsets.fromLTRB(25, 12.5, 25, 25),
            child: TextField(
              controller: _passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Password',
              ),
            ),
          ),
          Container(
              margin: const EdgeInsets.only(bottom: 25),
              child: Row(
                children: [
                  Expanded(
                      child: Column(
                    children: [
                      ElevatedButton(
                          onPressed: () => {
                            login(context,_emailController.text, _passwordController.text),
                            //     getCurrentSession(),
                              },
                          child: const Text('Login'))
                    ],
                  )),
                ],
              ))
        ],
      ),
    ),
  );
}

这是 Flutter Doctor -v 的输出

flutter doctor -v
[√] Flutter (Channel stable, 3.0.1, on Microsoft Windows [Version 10.0.19044.1706], locale en-US)
    • Flutter version 3.0.1 at C:\sdk\flutter_windows_2.10.5-stable\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision fb57da5f94 (3 weeks ago), 2022-05-19 15:50:29 -0700
    • Engine revision caaafc5604
    • Dart version 2.17.1
    • DevTools version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
    • Android SDK at C:\Users\sinne\AppData\Local\Android\sdk
    • Platform android-32, build-tools 32.1.0-rc1
    • Java binary at:
      C:\Users\sinne\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\211.7628.21.2111.8309675\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.11.10)
    • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
    • Visual Studio Community 2019 version 16.11.32126.315
    • Windows 10 SDK version 10.0.22000.0

[√] Android Studio (version 2021.1)
    • Android Studio at C:\Users\sinne\AppData\Local\JetBrains\Toolbox\apps\AndroidStudio\ch-0\211.7628.21.2111.8309675
    • Flutter plugin version 67.1.1
    • Dart plugin version 211.7817
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)

[√] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.19044.1706]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 102.0.5005.63
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 102.0.1245.30

[√] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

【问题讨论】:

    标签: flutter dart appwrite


    【解决方案1】:

    我建议的一件重要事情是确保只有 1 个客户端实例。客户端维护身份验证状态,并且拥有多个实例可能会导致很多问题。一种方法是使用单例模式:

    // libs/api/client.dart
    
    import 'package:appwrite/appwrite.dart';
    
    class ApiClient {
      Client get _client {
        Client client = Client();
    
        client
        .setEndpoint('https://your.appwrite.url/v1')
        .setProject('yourNetflixClone')
        .setSelfSigned();
    
        return client;
      }
    
      static Account get account => Account(_instance._client);
      static Database get database => Database(_instance._client);
      static Storage get storage => Storage(_instance._client);
    
      static final ApiClient _instance = ApiClient._internal();
      ApiClient._internal();
      factory ApiClient() => _instance;
    }
    

    然后,在您的代码中,您可以导入 ApiClient 并像这样使用它:

    import 'package:almostNetflix2/api/client.dart';
    
    final result = await ApiClient.account.createSession(email: email, password: password);
    

    如需更深入的教程,请参阅Almost Netflix series 中的Flutter article

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      相关资源
      最近更新 更多