Code Monkey home page Code Monkey logo

sdk-for-flutter's Introduction

Appwrite Flutter SDK

pub package License Version Build Status Twitter Account Discord

This SDK is compatible with Appwrite server version 1.5.x. For older versions, please check previous releases.

Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to https://appwrite.io/docs

Appwrite

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  appwrite: ^12.0.1

You can install packages from the command line:

flutter pub add appwrite

Getting Started

Add your Flutter Platform

To init your SDK and start interacting with Appwrite services, you need to add a new Flutter platform to your project. To add a new platform, go to your Appwrite console, choose the project you created in the step before, and click the 'Add Platform' button.

From the options, choose to add a new Flutter platform and add your app credentials. Appwrite Flutter SDK currently supports building apps for Android, iOS, Linux, Mac OS, Web and Windows.

If you are building your Flutter application for multiple devices, you have to follow this process for each different device.

Android

For Android first add your app name and package name, Your package name is generally the applicationId in your app-level build.gradle file. By registering your new app platform, you are allowing your app to communicate with the Appwrite API.

In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the <application> tag, along side the existing <activity> tags in your AndroidManifest.xml. Be sure to replace the [PROJECT_ID] string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in the console.

<manifest ...>
    ....
    <application ...>
        ....
        <!-- Add this inside the <application> tag, along side the existing <activity> tags -->
        <activity android:exported="true" android:name="com.linusu.flutter_web_auth_2.CallbackActivity" >
            <intent-filter android:label="flutter_web_auth_2">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="appwrite-callback-[PROJECT_ID]" />
            </intent-filter>
        </activity>
    </application>
</manifest>

iOS

For iOS first add your app name and Bundle ID, You can find your Bundle Identifier in the General tab for your app's primary target in Xcode.

The Appwrite SDK uses ASWebAuthenticationSession on iOS 12+ and SFAuthenticationSession on iOS 11 to allow OAuth authentication. You have to change your iOS Deployment Target in Xcode to be iOS >= 11 to be able to build your app on an emulator or a real device.

  1. In Xcode, open Runner.xcworkspace in your app's ios folder.
  2. To view your app's settings, select the Runner project in the Xcode project navigator. Then, in the main view sidebar, select the Runner target.
  3. Select the General tab.
  4. In Deployment Info, 'Target' select iOS 11.0

Linux

For Linux add your app name and package name, Your package name is generally the name in your pubspec.yaml file. If you cannot find the correct package name, run the application in linux, and make any request with proper exception handling, you should get the application ID needed to add in the received error message.

Mac OS

For Mac OS add your app name and Bundle ID, You can find your Bundle Identifier in the General tab for your app's primary target in Xcode.

The Appwrite SDK uses ASWebAuthenticationSession on macOS 10.15+ to allow OAuth authentication. You have to change your macOS Deployment Target in Xcode to be macOS >= 10.15 to be able to build your app for macOS.

Web

Appwrite 0.7, and the Appwrite Flutter SDK 0.3.0 have added support for Flutter Web. To build web apps that integrate with Appwrite successfully, all you have to do is add a web platform on your Appwrite project's dashboard and list the domain your website will use to allow communication to the Appwrite API.

For web in order to capture the OAuth2 callback URL and send it to the application using JavaScript postMessage(), you need to create an html file inside ./web folder of your Flutter project. For example auth.html with the following content.

<!DOCTYPE html>
<title>Authentication complete</title>
<p>Authentication is complete. If this does not happen automatically, please
close the window.
<script>
  window.opener.postMessage({
    'flutter-web-auth-2': window.location.href
  }, window.location.origin);
  window.close();
</script>

Redirection URL passed to the authentication service must be the same as the URL on which the application is running (schema, host, port if necessary) and the path must point to created HTML file, /auth.html in this case. The callbackUrlScheme parameter of the authenticate() method does not take into account, so it is possible to use a schema for native platforms in the code.

Flutter Web Cross-Domain Communication & Cookies

While running Flutter Web, make sure your Appwrite server and your Flutter client are using the same top-level domain and the same protocol (HTTP or HTTPS) to communicate. When trying to communicate between different domains or protocols, you may receive HTTP status error 401 because some modern browsers block cross-site or insecure cookies for enhanced privacy. In production, Appwrite allows you set multiple custom-domains for each project.

Windows

For Windows add your app name and package name, Your package name is generally the name in your pubspec.yaml file. If you cannot find the correct package name, run the application in windows, and make any request with proper exception handling, you should get the application id needed to add in the received error message.

Init your SDK

Initialize your SDK with your Appwrite server API endpoint and project ID, which can be found in your project settings page.

import 'package:appwrite/appwrite.dart';

void main() {
  Client client = Client();

  client
    .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint
    .setProject('5e8cf4f46b5e8') // Your project ID
    .setSelfSigned() // Use only on dev mode with a self-signed SSL cert
  ;
}

Before starting to send any API calls to your new Appwrite instance, make sure your Android or iOS emulators has network access to the Appwrite server hostname or IP address.

When trying to connect to Appwrite from an emulator or a mobile device, localhost is the hostname for the device or emulator and not your local Appwrite instance. You should replace localhost with your private IP as the Appwrite endpoint's hostname. You can also use a service like ngrok to proxy the Appwrite API.

Make Your First Request

Once your SDK object is set, access any of the Appwrite services and choose any request to send. Full documentation for any service method you would like to use can be found in your SDK documentation or in the [API References](https://appwrite.io/docs) section.

// Register User
Account account = Account(client);
final user = await account
  .create(
    userId: ID.unique(), email: "[email protected]", password: "password", name: "Walter O'Brien"
  );

Full Example

import 'package:appwrite/appwrite.dart';

void main() {
  Client client = Client();


  client
    .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint
    .setProject('5e8cf4f46b5e8') // Your project ID
    .setSelfSigned() // Use only on dev mode with a self-signed SSL cert
    ;


  // Register User
  Account account = Account(client);

  final user = await account
    .create(
      userId: ID.unique(), email: "[email protected]", password: "password", name: "Walter O'Brien"
    );
}

Error Handling

The Appwrite Flutter SDK raises AppwriteException object with message, type, code and response properties. You can handle any errors by catching AppwriteException and present the message to the user or handle it yourself based on the provided error information. Below is an example.

Account account = Account(client);

try {
  final user = await account.create(userId: ID.unique(), email: "[email protected]", password: "password", name: "Walter O'Brien");
  print(user.toMap());
} on AppwriteException catch(e) {
  //show message to user or do other operation based on error as required
  print(e.message);
}

Learn more

You can use the following resources to learn more and get help

Contribution

This library is auto-generated by Appwrite custom SDK Generator. To learn more about how you can help us improve this SDK, please check the contribution guide before sending a pull-request.

License

Please see the BSD-3-Clause license file for more information.

sdk-for-flutter's People

Contributors

abnegate avatar antoniopetricc avatar christyjacob4 avatar eldadfux avatar lohanidamodar avatar meldiron avatar torstendittmann avatar visheshjindal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdk-for-flutter's Issues

πŸ› Bug Report: AppwriteException: null, Concurrent modification during iteration: Instance(length:2) of '_GrowableList'. (0)

πŸ‘Ÿ Reproduction steps

when i tried to log in session.

πŸ‘ Expected behavior

πŸ‘Ž Actual Behavior

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

🎲 Appwrite version

Version 0.11.x

πŸ’» Operating system

Windows

🧱 Your Environment

Flutter

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› Bug Report: ApiClient.account.get(); throw an error

πŸ‘Ÿ Reproduction steps

Just call ApiClient.account.get() when you are not loged in. I expected to get a null but this is not nullable value. Im getting something like this

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: AppwriteException: general_unauthorized_scope, User (role: guest) missing scope (account) (401)
E/flutter (18416): #0 ClientMixin.prepareResponse (package:appwrite/src/client_mixin.dart:73:9)
E/flutter (18416): #1 ClientIO.call (package:appwrite/src/client_io.dart:256:14)
E/flutter (18416):
E/flutter (18416): #2 Account.get (package:appwrite/services/account.dart:20:17)
E/flutter (18416):
E/flutter (18416): #3 MyHomePage.getAccount (package:tanangaapps/main.dart:66:23)
E/flutter (18416):

And this is how it looks in account.dart appwrite file:

/// Get Account
///
/// Get currently logged in user data as JSON object.
///
Future<models.User> get() async {
const String path = '/account';

final Map<String, dynamic> params = {};

final Map<String, String> headers = {
  'content-type': 'application/json',
};

final res = await client.call(HttpMethod.get,
    path: path, params: params, headers: headers);
return models.User.fromMap(res.data);

}

πŸ‘ Expected behavior

It should return null or empty user

πŸ‘Ž Actual Behavior

ERROR. Is it ok? It looks wierd

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

MacOS

🧱 Your Environment

I use digitalOcean Appwrite 0.13.4 and my apprwite version in pubspec.yaml : appwrite: ^4.0.2

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› - User Object gives an error

Issue description:

when I execute User _response = await Connection.instance.account.get();, it gives an error:

E/flutter ( 6728): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'List<dynamic>' is not a subtype 
of type 'Map<String, dynamic>'
E/flutter ( 6728): #0      new User.fromMap (package:appwrite/src/models/user.dart:49:37)
E/flutter ( 6728): #1      Account.get (package:appwrite/services/account.dart:21:24)
E/flutter ( 6728): <asynchronous suspension>
E/flutter ( 6728): #2      UserModel.setUserData (package:expirapp/models/UserModel.dart:215:21) <- the mentioned line of code
E/flutter ( 6728): <asynchronous suspension>

I suppose the cause of this issue is that the resposne map in account.dart:19:

final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers); 

is a map with a key "prefs" -> List:
image
Which later, in user.dart:41:

    return User(
      $id: map['\$id'],
      name: map['name'],
      registration: map['registration'],
      status: map['status'],
      passwordUpdate: map['passwordUpdate'],
      email: map['email'],
      emailVerification: map['emailVerification'],
      prefs: Preferences.fromMap(map['prefs']),
    );

gets treated as a map.

Can't get sessionId by OAuth

When login with createOAuth2Session(...), the Response is null. and there is no way to get sessionId.

// login code
var sessionId = ""
account.createOAuth2Session(provider: provider)
.then((value) {
       // value is null
       sessionId = ""; // TODO
});


// logout code
account.deleteSession(sessionId: sessionId)

only getSessions can get all sessions, but i don't know which session is my current session.

πŸ› Bug Report: createFloatAttribute() 'toDouble' was called on null.

πŸ‘Ÿ Reproduction steps

Execute the following function:

database.createFloatAttribute(
          collectionId: "collection",
          key: "someKey",
          xrequired: true)

πŸ‘ Expected behavior

The function should be executed without an error.

πŸ‘Ž Actual Behavior

The function returns:

NoSuchMethodError: The method 'toDouble' was called on null.
Receiver: null
Tried calling: toDouble()
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:68:5)
#1      new AttributeFloat.fromMap (package:dart_appwrite/src/models/attribute_float.dart:49:32)
#2      Database.createFloatAttribute (package:dart_appwrite/services/database.dart:279:34)
<asynchronous suspension>

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Linux

🧱 Your Environment

Appwrite 0.12

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› Bug Report: Users not found

πŸ‘Ÿ Reproduction steps

Hi,

This code "Users users = Users(client);" does not work with flutter SDK. Is there a difference between dart and flutter SDK? Since this same chunk of code is working with dart sdk

πŸ‘ Expected behavior

Dart or flutter normally share same code

πŸ‘Ž Actual Behavior

Users not defined in flutter appwrite package

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Linux

🧱 Your Environment

I am using digital ocean

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Use package_info_plus instead of package_info

Description

I saw on pub.dev that the appwrite package depends on package_info. I recommend to switch to package_info_plus, because of the platform support:

Platform Β package_info Β package_info_plus
Android Β βœ… Β  βœ…
iOS Β βœ… Β  βœ…
Web  ❌ Β  βœ…
Linux  ❌ Β  βœ…
macOS  ❌ Β  βœ…
Windows  ❌ Β  βœ…

The migration is very easy. Just replace package_info_plus package with package_info package in pubspec.yaml and update the imports.

Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'

I have question on my flutter App to login Appwrite. I tried to server down the Appwrite and login the system. It is supposed to exception and print the error message. However it didn’t work on my below code and get the below error log

Login code

Future login({String email, String password}) async {
    try {
      await account.createSession(email: email, password: password);
      return true;
    } on AppwriteException catch (e) {
      print('ApiService login error ' + e.message);
      return false;
    }
  }

Error log

[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'


#0      Client.call      package:appwrite/client.dart:153
<asynchronous suspension>
#1      ApiService.login     package:praise/…/data/ApiService.dart:28
<asynchronous suspension>
#2      HomeRepository.login.<anonymous closure> (package:praise/pages/home/data/home_repository.dart)        package:praise/…/data/home_repository.dart:1
<asynchronous suspension>

I use appwrite: 0.5.0-dev.1

πŸ› Bug Report: account.get() throwing error as appwrite returns int instead of bool

πŸ‘Ÿ Reproduction steps

Flutter v.2.8.1
Dart v2.15.1
Appwrite v0.11.0.170

Create account
login:
await account.createSession(email: email, password: password);
call account.get:
await account.get();

E/flutter (30394): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'int' is not a subtype of type 'bool'
E/flutter (30394): #0      new User.fromMap (package:appwrite/src/models/user.dart:45:18)
E/flutter (30394): #1      Account.get (package:appwrite/services/account.dart:21:24)

Can be solved by modifying \lib\src\models\user.dart:45 to:
status: map['status']== 0 ? false : true,

πŸ‘ Expected behavior

Return the user data

πŸ‘Ž Actual Behavior

throws type error

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Linux

🧱 Your Environment

Running manual docker config (needed different ports)

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Collection not found after create the document on the Collection "Userdata" database

Hi All,

I tried to create the document on database. I created Collection "Userdata" and get the collectionID. After run the below createUser function. I got the error Collection not found. But I have provided the collectionID. What happen on the AppWrite server or on my code?

  Client appwriteClient = Client();

  appwriteClient
        .setEndpoint(appWriteServerUrl)
        .setProject(_projectId)
        .setSelfSigned();
  account = Account(appwriteClient);
  database = Database(appwriteClient);
  storage = Storage(appwriteClient);

  createUser({String username}) {
    dynamic _data;
    _data = {"username": username};
    Future result = database.createDocument(
      collectionId: '5f2c17b7d74ae',
      data: _data,
      read: [],
      write: [],
    );

    result.then((response) {
      print("create user in Users database success====================");
      print(response);
    }).catchError((error) {
      print("create user in Users database error====================");
      print(error.response);
    });
  }

Error throw on below

flutter: create user in Users database error====================
flutter: {"message":"Collection not found","code":404,"version":"0.6.2"}

Screenshot 2020-08-06 at 10 54 03 PM

πŸ› Bug Report: Failed to login Appwrite Anonymous account on Microsoft Edge (Chromium) on Flutter Web with appwrite 3.0.1 package

πŸ‘Ÿ Reproduction steps

Failed to login Appwrite Anonymous account on Microsoft Edge (Chromium) on Flutter Web with appwrite 3.0.1 package.

But it can login Appwrite anonymous account using other browser such as Microsoft Internet Explorer, Google Chrome and any Safari in MacOS/ iOS/iPad OS. Is it the any workaround to solve this?

πŸ‘ Expected behavior

The web page load and login the Appwrite Anonymous account and get the database document.

Here is the screen dump when I use other browser Google Chrome.

10140187-08E8-4E32-8260-F371C689D2F3
46D3F66E-B7AE-4AD3-8C50-DB33162822FE

πŸ‘Ž Actual Behavior

The web page load but fail to login the Appwrite Anonymous account and can’t get the database document to display the webpage content.

Here is the screen dump when I use other browser Microsoft Edge (Chromium).

5CAC21D6-803D-4DC9-B521-B15658CAE7D3

I used Sentry.io to capture the error message on below as well.

minified:hd: AppwriteException: Cannot create an anonymous user when logged in. (401)
  at Object.c(main.dart.js:2347:3)
  at Object.a0(main.dart.js:2354:15)
  at <fn>(main.dart.js:34070:3)
  at ajG.a(main.dart.js:3535:62)
  at ajG.$2(main.dart.js:28616:14)
  at aiw.$1(main.dart.js:28610:21)
  at Object.ajt(main.dart.js:3773:19)
  at Lm.<fn>(main.dart.js:69535:68)
  at NM.m5(main.dart.js:29453:12)
  at aeI.$0(main.dart.js:28929:11)

Based on the Appwrite Error code page for 401, it is Missing or incorrect authentication credentials can happen when the API key or user permission is not sufficient.

The strange thing is when the browser is Chrome, it is no these error. When the browser is Microsoft Edge (Chromium), what the anonymous authentication credentials information is incorrect or missing? It caused the login failed.

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Something else

🧱 Your Environment

I use Flutter Web on the Appwrite 3.0.1 package. The Appwrite server is 0.12

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Add Windows support for the Appwrite Flutter SDK

Most features of the Appwrite Flutter SDK should already work with Windows apps out of the box. One specific area that still lacks support is our OAuth login. For us to enable OAuth login we actually need to add Windows support on the Web auth plugin https://github.com/LinusU/flutter_web_auth we use as a dependency.

The Web Auth library already support web auth login for Android, iOS, and MacOS. Once Windows support is added, we should just update the Appwrite SDK to use the latest version of the auth plugin.

This actual PR should be made against https://github.com/LinusU/flutter_web_auth, but will be happy to make this issue valid for Appwrite SWAG during Hacktoberfest.

getFilePreview() not returning a Future

In Flutter I am working on a storage list page.

To preview the file/icon i am about to use getFilePreview(). How come this is not returning a future? It is just returning a String. I would expect it to return Future like fx. getFile() ?

This is also the case for: getFileDownload() and getFileView()

πŸ“š Documentation:

πŸ’­ Description

Hey,

How would I configure different appwrite projects per flavor? (Development, Staging, Production)

For iOS it is simple by just providing a different project id when initializing the client.

Tho I am having issues with the android setup, where I need to additionally add the new activity with the project id as a key

is there some documentation available or if not could you provide me with some?

Best regards,
Marcel

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Potential crash in `Client.call`

We are using some new app write APIs that are not yet documented. In this case, we are using the Client to access the Rest Endpoints.
This is obviously more of a "power" user thing, but I thought it might be good to mention it.

The Client.call will crash if the provided params or headers are empty.

Future<Response> call(HttpMethod method,
      {String path = '',
      Map<String, String> headers = const {},
      Map<String, dynamic> params = const {},
      ResponseType? responseType,
})

The problem is that const {} will create unmodifiable maps which will result in a crash.
For example params.removeWhere((key, value) => value == null); a few lines after.

Some other code is working around that for example createJwt which creates an empty but not const map.

  Future<Response> createJWT() {
    final String path = '/account/jwt';

    final Map<String, dynamic> params = {};

    final Map<String, String> headers = {
      'content-type': 'application/json',
    };

    return client.call(HttpMethod.post,
        path: path, params: params, headers: headers);
  }

This could be reduced to this:

  Future<Response> createJWT() {
   return client.call(HttpMethod.post, path: '/account/jwt', headers: { 'content-type': 'application/json' });
  }

Null pointer in `createOAuth2Session`

When calling createOAuth2Session in the Flutter SDK, the method crashes if success or failure is null which is allowed since both params are optional.

Here is the line and a potential fix:

    params.forEach((key, value) {
      if (value is List) {
        for (var item in value) {
          query.add(Uri.encodeComponent(key + '[]') +
              '=' +
              Uri.encodeComponent(item));
        }
      } else if(value != null) { // null check fixes the crash.
        // can not parse null value into a Uri.
        query.add(Uri.encodeComponent(key) + '=' + Uri.encodeComponent(value));
      }
    });

I would love to provide a PR that fixes this issue, but i am not sure if i can just fork the repo. Don't you generate the dart code?

@TorstenDittmann

πŸš€ Feature: Add SetKey method to Client class.

πŸ”– Feature description

Currently, the SetKey method does not exist. It does in dart_appwrite.

🎀 Pitch

When trying to build an admin application that requires access to all artefacts outside the normal permissions, you need to be able to set the api key to use. See: https://appwrite.io/docs/getting-started-for-server#apiKey

However, the SetKey method is not exposed in the flutter_appwrite package. it is in all the other libraries (nodejs etc).

I have tried to switch my app to use dart_appwrite, but then I loose the appwrite/models and session classes.

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

4xx call throws DioError which exposes implementation details

The lib uses dio internally which forces consumers to catch the error if an unsuccessful call throws a DioError.
We currently use this helper method to map unsuccessful calls to own exception/other exception types.

// Some calls fail because Dio is used internally and this will throw instead
  // of returning a 4xx response.
  Future<R> _catchApiErrors<R>(FutureOr<R> Function() call) async {
    try {
      return await call();
    } on DioError catch (error) {
      if (error.response.statusCode == 401) {
        throw ApiException.unauthorized(); // own exception type

      }
      rethrow;
    }
  }

I just want to point out that this is not an issue atm, but it might be a nice thing to improve.
Feel free to close this issue πŸ‘

πŸ› Bug Report: Flutter Windows Concurrent Modification Error

πŸ‘Ÿ Reproduction steps

When I try database.list() with Queries or teams.getMemberships() throws a Unhandled Exception: AppwriteException: null, Concurrent modification during iteration: Instance(length:2) of '_GrowableList'

πŸ‘ Expected behavior

It should fetch the polled results normally with results like in Flutter Android, iOS and Web.

πŸ‘Ž Actual Behavior

Constantly throws a Unhandled Exception: AppwriteException: null, Concurrent modification during iteration: Instance(length:2) of '_GrowableList' or may not. It was hard understanding the behaviour. When I debugged with VS Code debugger it shows that the cascade :

dart:_internal/iterable.dart file in flutter line 336 which throws the Concurrent modification error => triggered by client_io.dart at line 180 which is iterating i think => triggered by line 251 still in client_io.dart which throws the error at line 264 in same file => my code..

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Windows

🧱 Your Environment

Version 0.13.4

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ“š Documentation: Using maps

πŸ’­ Description

Hi, is it possible to use Maps instead of arrays with the database? Thanks

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› Bug Report: Realtime subscribe creates two websocket connections

πŸ‘Ÿ Reproduction steps

I use this code to connect:

class _MyChatPageState extends State<ChatPage> {
  AuthState? _state;
  late final Client client = Client();
  late final Realtime realtime;
  late final RealtimeSubscription _chat;
  final String chatCollectionId = "61346bcfbd96e";

  @override
  void initState() {
    super.initState();
    client.setEndpoint(Constants.endPoint).setProject(Constants.projectId);
    realtime = Realtime(client);
    subscribeChat();
  }

  @override
  void deactivate() {
    _chat.close();
    super.deactivate();
  }

  subscribeChat() {
    try {
      _chat = realtime.subscribe(['collections.$chatCollectionId.documents']);
    } on AppwriteException catch (error) {
      print(error.message);
    }
    _chat.stream.listen((data) {
      if (data.payload.isNotEmpty) {
        switch (data.event) {
          case "database.documents.create":
            print(data.payload);
            break;
          default:
            break;
        }
      }
    });
  }
}

i think it tries to create a reconnect after first connect.. the second one can be closed on dispose, but the first one can not be closed

Bildschirmfoto 2021-10-18 um 14 37 13

Bildschirmfoto 2021-10-18 um 14 38 19

πŸ‘ Expected behavior

1 connection for 1 subscribe :)

πŸ‘Ž Actual Behavior

2 connections for 1 subscribe :)

🎲 Appwrite version

Version 2.0.x

πŸ’» Operating system

Linux

🧱 Your Environment

No response

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

[BUG] Converting anonymous account with OAuth2

When initializing an OAuth2 session, the cookie that would indicates migrating an anonymous account to a full account gets lost in the WebView.

I think one of the possible solution at the moment (that will also work for other clients including Android (kotlin), iOS (swift), as I think Android will have similar problem at the moment)

  1. in the createOAuth2Session endpoint we will receive the cookie from the client,
  2. using that cookie Appwrite will generate some token that will identify the currently active session/user and passing that token around during redirection
  3. so when finally redirected to create actual session, Appwrite can use that token to identify the active session if any

Or similar thing might be done, instead of passing token around during redirection, saving some details temporarily in the DB/or somewhere, that can be used to identify the request and session to make the decision
We will have more research and possible solution around it.

AppwriteException: User (role: guest) missing scope (documents.write) (401) while creating new document

Unable to add a document in the database. I have not authenticated the user.
Here is my code.

//
Client client = Client();
client.setEndpoint(databaseUrl).setProject("6156deb490468").setSelfSigned(status: true);
Database database = Database(client);
database
.createDocument(
collectionId: '6156e69af2f61',
data: {
"name": "India",
"capital": "Delhi",
},
write: [""],
read: ["
"],
)
.then((value) => print(value.$id))
.catchError((e) {
print(e.toString());
});
//

Am I missing something?

πŸš€ Feature: Url to view file in addition to uInt8List

πŸ”– Feature description

I'm currently developing a Flutter App for mobile, web and desktop. Each platform has it's unique challenges. Currently I'm trying to play video from my appwrite backend. While it is no problem to create a local file from a byteList on mobile and play a video from it, there is no play from file on web.

Of course, I can call the appwrite rest Api with the /view directive and view the file in my browser. What about some way to get the URL to pass it to a audio or video player on web.

As I can see, the getFileDownload and getFileView methods do basically the same thing in the Appwrite Flutter SDK.

🎀 Pitch

What if getFileView would actually return a URL to access the File. The URL could be passed to any Video or Audio Player package and would make the appwrite flutter sdk work better on web.

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› Bug Report: Error when widget binding is not initialized

πŸ‘Ÿ Reproduction steps

  • Create a flutter project
  • Create appwrite project and add flutter platform
  • Install appwrite package to flutter project
  • Initialize client as explained on example or readme

πŸ‘ Expected behavior

Connect to appwrite server

πŸ‘Ž Actual Behavior

Throwing exception
Null check operator used on a null value

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Windows

🧱 Your Environment

Appwrite version: 3.0.1

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸ› Bug Report: Unable to receive any messages from realtime

πŸ‘Ÿ Reproduction steps

I wrote realtime code with reference to the document, but I still can't receive any messages.
Can someone provide a example project for reference?
// DI code

/// .... other ....
  @lazySingleton
  Client get client => Client()
    ..setEndpoint("http://localhost/v1")
    ..setProject("<my-proj-id>")
    ..setSelfSigned(status: true); 

  // Register User
  @lazySingleton
  Account get account => Account(sl<Client>());

  // Subscribe to files channel
  @lazySingleton
  Realtime get realtime => Realtime(sl<Client>());

/// .... other ....
// run on user logged in
  final rl = sl<Realtime>() // get Realtime from DI, This is valid for `database`, `account` and other components
      ..subscribe(const [
        'account',
        'collections',
        'users',
        'database',
        'documents',
        'documents.<some-doc-id>',
      ]).stream.listen((event) {
        print("debug realtime# event: ${event.events}, ${event.payload}");
      });

I have tried to modify the account name, create a new collection, modify the collection properties, add documents, modify the contents of documents and so on, but I can't receive any messages from realtime.
(Of course, the read and write permissions of the collection are role:all, and I have tried user:XXXX, which has no effect)

πŸ‘ Expected behavior

print any event message from realtime.

πŸ‘Ž Actual Behavior

on windows clinet and flutter web(chrome)

subscription: ws://localhost/v1/realtime?project=<my-proj-od>&channels%5B%5D=account&channels%5B%5D=collections&channels%5B%5D=users&channels%5B%5D=database&channels%5B%5D=documents&channels%5B%5D=documents.<some-doc-id>

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

Windows

🧱 Your Environment

server:

  • Centos-Docker / Windows10-WSL2-Docker
  • appwrite: 0.13.4 / 0.14.0(can not be used)

client:

  • Windows10
  • appwrite(flutter): 4.0.2

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Dart Code Format

By default the dart formatter user the indentation of 2 space.
I am working with flutter for a long time and new focus on much of these.

Today when tried to contribute to this project I found that the complete code gets modified because of the indentation.

Here modify means, it modifies the indentation of every line.
Now the problem is if I send a pull request with that many changes then it would be difficult to find my code change.

I am raising this issue so that beginner and intermediate can contribute without having these difficulties.

Here is one issue about two space indentation problem: Dart-Code/Dart-Code#914

PS: I tried to set the default indentation to 4 spaces that are being used in this project but I failed.
So, I suggest we should go with the default because dart already has a standard formatter.

There are two files in the SDK which are enums.dart and service.dart which use 2 space indentation.

Thank you

πŸš€ Feature: Subscribe to event where an user has write permissions, beside to read permissions

πŸ”– Feature description

At this moment you can only subscribe to events where the user has read permissions. There should be an option to listen to events of documents you created.
Some collections (like user images in a dating app) are readable to other members of the app, but when a user wants to list his own userimages and listen to changes, it needs to listen to documents that the user created.

The current situation is that i get all events of all users when i am trying to listen the userimages collection.

🎀 Pitch

This feature would be a great addition to the current possibilities. It falls in line with the current method to listen to events where the user has read permission.

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Upgrade our issue templates to use GitHub issue forms ✍️

Introduction

GitHub has recently rolled out a public beta for their issue forms feature. This would allow you to create interactive issue templates and validate them 🀯.

Appwrite currently uses the older issue template format. Your task is to create GitHub issue forms for this repository. Please use Appwrite's issue templates as a reference for this PR.

Tasks summary:

  • Fork & clone this repository
  • Prepare bug report issue form in .github/ISSUE_TEMPLATE/bug.yaml
  • Prepare documentation issue form in .github/ISSUE_TEMPLATE/documentation.yaml
  • Prepare feature request issue form in .github/ISSUE_TEMPLATE/feature.yaml
  • Push changes to master and test issue forms on your fork
  • Submit pull request

If you need any help, reach out to us on our Discord server.

Are you ready to work on this issue? πŸ€” Let us know, and we will assign it to you 😊

Happy Appwriting!

Add Linux support for the Appwrite Flutter SDK

Most features of the Appwrite Flutter SDK should already work with Linux apps out of the box. One specific area that still lacks support is our OAuth login. For us to enable OAuth login we actually need to add Linux support on the Web auth plugin https://github.com/LinusU/flutter_web_auth we use as a dependency.

The Web Auth library already support web auth login for Android, iOS, and MacOS. Once Linux support is added, we should just update the Appwrite SDK to use the latest version of the auth plugin.

This actual PR should be made against https://github.com/LinusU/flutter_web_auth, but will be happy to make this issue valid for Appwrite SWAG during Hacktoberfest.

Unnecessary Overhead: the init() method

Been looking through the SDK to write a client-dotnet twig, and I cannot wrap my head around the Flutter init() method. It is clearly to get cookies and set them within the CookieJar, and it turns itself off after it is bool initialized.

I do not see the purpose of calling this in EVERY CALL() method.

There is no reason to. The only cookie necessary is a Login Cookie, and I solved this problem in Dotnet by putting the Cookie code in the initial Client() constructor (to attach the CookieJar) and in the Login Method itself (to add the proper cookie). The init() flutter code WORKS, but it is terrible etiquette. Once the variable has been set to false, which invariably it has after the program finds that one necessary cookie, it continues to call an empty method for EVERY Call() event ever.

It is bad code smell especially when it introduces the overhead of unnecessarily checking every Call() event for a true/false condition that is surely not going to change unless the user explicitly logs out, and even then, the Login method is still the best place for this kind of Cookie set.

CookieJar not initialized when creating OAuth2 session

I'm testing out the package, awesome work. I found a small issue though. It looks like if the first interaction with the sdk is the createOAuth2Session method, the cookieJar in the client never gets initialized so it fails with a null error when calling the following:

client.cookieJar.saveFromResponse(Uri.parse(client.endPoint), cookies);

πŸ› Bug Report: No file sent (400)

πŸ‘Ÿ Reproduction steps

When i try upload image

πŸ‘ Expected behavior

it should be uploaded to storage

πŸ‘Ž Actual Behavior

returns me error AppwriteException: No file sent (400)

this is my code, i try to use client and server sdk, neither works

Future<Map<String, String>> uploadFile(PlatformFile file) async {
    final String field = randomAlphaNumeric(10);

    final uploadFile = MultipartFile(field, file.readStream!, file.size);

    final res = await storage.createFile(
      file: uploadFile,
      read: ['team:${team!.$id}'],
      write: ['team:${team!.$id}'],
    );

    return {'type': file.extension!, 'id': res.$id};
  }

🎲 Appwrite version

Version 2.0.x

πŸ’» Operating system

Linux

🧱 Your Environment

i use 2.8.0 flutter version

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

CERTIFICATE*VERIFY*FAILED: certificate has expired on Windows 10

This is the error I get when trying to connect to my appwrite server. I have a valid SSL (When visiting the address on Chrome give no SSL issues).

I have all the .env settings at default except the domain and the require ssl.

`[ERROR:flutter/lib/ui/uidartstate.cc(199)] Unhandled Exception: AppwriteException: HandshakeException: Handshake error in client (OS Error:

CERTIFICATEVERIFYFAILED: certificate has expired(../../third_party/boringssl/src/ssl/handshake.cc:359)) (0)`

Flutter doctor:
[√] Flutter (Channel stable, 2.5.1, on Microsoft Windows [Version 10.0.19043.1237], locale en-US) β€’ Flutter version 2.5.1 at C:\Users\Elias\flutter β€’ Upstream repository https://github.com/flutter/flutter.git β€’ Framework revision ffb2ecea52 (2 weeks ago), 2021-09-17 15:26:33 -0400 β€’ Engine revision b3af521a05 β€’ Dart version 2.14.2

πŸ› Bug Report: WidgetsBinding.instance?.removeObserver

πŸ‘Ÿ Reproduction steps

Hi.

I updated my appwrite version to the latest one and now I see this red warnings in the console.
Please take a look.

Screenshot 2022-05-25 at 00 06 50

πŸ‘ Expected behavior

clear console

πŸ‘Ž Actual Behavior

Red warnings in the console

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

MacOS

🧱 Your Environment

Latest version

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

πŸš€ Feature: Change cookie storage

πŸ”– Feature description

Currently, the cookies are stored in files that can be accessed by other apps.

🎀 Pitch

I would suggest that you change the location of the cookies. I would use the plugin flutter_secure_storage for this purpose. I have also implemented this locally for my own projects. If desired, I can provide a corresponding pull request.

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Port # seems to be ignored

I initialize the client endpoint to localhost with a given port.

  final Client _client = Client()
      .setEndpoint('http://localhost:8089/v1')
      .setProject(projectId)
      .setSelfSigned(status: true);

But then when I make any request using the client I get the following error.

E/flutter ( 5606): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: DioError [DioErrorType.DEFAULT]: SocketException: OS Error: Connection refused, errno = 111, address = localhost, port = 59488

The port number in the error message changes every time a request is made.
Is there some other way of specifying the port number?

Error to create the File using storage.createFile

HI All,

I have the method to create the file by the below code. However I got the error after run the method.

Code for CreateFile

  createFile(
      {@required File file, @required List read, @required List write}) async {
    String basename = path.basename(file.path);
    MediaType contentType = MediaType('image', 'jpg');
    try {
      print("file.path----------${file.path}");

      Future result = storage.createFile(
        file: await MultipartFile.fromFile(file.path,
            filename: basename, contentType: contentType),
        read: [],
        write: [],
      );

      result.then((response) {
        print("success====================");
        print(response.toString());
      }).catchError((error) {
        print("result error====================");
        print(error.toString());
      });
    } catch (error) {
      print("error====================");
      print(error.toString());
    }
  }

Error message

flutter: file.path----------/Users/patrick/Library/Developer/CoreSimulator/Devices/E15F6EA6-8D1F-4E79-9867-86AB8CDEE10D/data/Containers/Data/Application/981407DA-A678-4492-9177-E71927D7C801/tmp/image_picker_A7A0A3E2-7EFA-4E13-9777-C22E2C40110B-88700-0000C79F50C38374.jpg
flutter: error====================
flutter: NoSuchMethodError: The method 'createFile' was called on null.
Receiver: null
Tried calling: createFile(file: Instance of 'MultipartFile', read: Instance(length:0) of '_GrowableList', write: Instance(length:0) of '_GrowableList')

Anyone can help to find what happen.

Regards

Patrick

401 error and missing scope when run playground-for-flutter

browser_adapter.dart:98 GET https://localhost/v1/account 401
js_primitives.dart:30  User (role: guest) missing scope (account)

Code is from: https://github.com/appwrite/playground-for-flutter. And I comment out the addHeader line:

client          .setEndpoint(              'https://localhost/v1')
 // Make sure your endpoint is accessible from your emulator, use IP if needed         
.setProject('60793ca4ce59e') // Your project ID          
.setSelfSigned() // Do not use this in production         
//.addHeader('Origin', 'http://localhost') ;

BTW, sdk for node works.

Creating document result in an error

Using this piece of code to add document it result in an error also into the /console I am unable to find button to add document to collection.
What am I doing wrong ?

    Future result = database.createDocument(
      collectionId: '<my id was here>',
      data: [ // Rules
        {
          "label": "Name",
          "key": "name",
          "type": "text",
          "default": "Empty Name",
          "required": true,
          "array": false
        },
        {
          "label": "Release Year",
          "key": "releaseYear",
          "type": "numeric",
          "default": 1970,
          "required": true,
          "array": false
        },
        {
          "label": "Notes",
          "key": "notes",
          "type": "text",
          "default": null,
          "required": false,
          "array": true
        }
      ],
      read: [],
      write: [],
    );

πŸ› Bug Report: Event is triggered multiple times when subscribing to multiple (different) channels

πŸ‘Ÿ Reproduction steps

Create, Update & Delete events are being triggered multiple times when subscribed to multiple channels.
In the example below there are 2 create events when a userimage is added.

First subscription:

subscribe() {
    if (userimagesSubscription == null) {
      userimagesSubscription = AppwriteApi.instance.realtime
          .subscribe(['collections.userimages.documents']);
      userimagesSubscription!.stream.listen((data) async {
        if (data.payload.isNotEmpty) {
          // Do some handling..
        }
      });
    }
  }

Second subscription:

subscribe() {
    if (interestSubscription == null) {
      interestSubscription = AppwriteApi.instance.realtime
          .subscribe(['collections.interest.documents']);
      if (interestSubscription != null) {
        interestSubscription!.stream.listen((data) async {
          if (data.payload.isNotEmpty) {
           // Do some handling..
          }
        });
      }
    }
  }

πŸ‘ Expected behavior

There should be only 1 trigger event per event.

πŸ‘Ž Actual Behavior

The debug console shows the following:

I/flutter ( 5914): subscription: wss://db.DOMAIN.nl/v1/realtime?project=6234aad9d50bf302d1b5&channels%5B%5D=collections.userimages.documents

I/flutter ( 5914): subscription: wss://db.DOMAIN.nl/v1/realtime?project=6234aad9d50bf302d1b5&channels%5B%5D=collections.userimages.documents&channels%5B%5D=collections.interest.documents

🎲 Appwrite version

Version 4.0.x

πŸ’» Operating system

Linux

🧱 Your Environment

No response

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Realtime User Auth

Using the branch here:

appwrite:
    git:
      url: https://github.com/appwrite/sdk-for-flutter
      ref: feat-realtime

I am trying to listen to auth states but I do not get any events at all.
Here is the code:

late RealtimeSubscription sub;

  void _incrementCounter() {
    setState(() {
      try {
        AppWrite.instance
            .login(email: '[email protected]', password: '12345678');
      } on AppwriteException catch (e) {
        print(e.message);
      }
      _counter++;
    });
  }

  @override
  void initState() {
    print('Starting');
    sub = AppWrite.instance.realtime.subscribe(['accounts']);
    print('Got Sub');
    sub.stream.listen((event) {
      print(event);
      var data = json.decode(event);
      print(data);
    });
    super.initState();
  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.