apstanisic / directus-dart Goto Github PK
View Code? Open in Web Editor NEWDirectus SDK for Dart and Flutter
License: MIT License
Directus SDK for Dart and Flutter
License: MIT License
I'm digging down a rabbit hole:
Is there a way to get a user object with custom fields? If not there should be. If yes can it be documented please.
Hello,
Can i get please example how to do fulltext search?
i tried to modify library with query with search param
await DirectusApi.sdk.items('Products').readMany(
query: Query(fields: ["id,name"], search: 'numb'),
filters: Filters(
{
'status': Filter.eq("published"),
},
),
);
with this im getting correctly product, but if i add translation relation, then i really dont know, that leads me to fulltext ability
Thanks!
I observe a lack of implementation for relational Filter.
How can I implement this with the current filter?
{
"author": {
"name": {
"_eq": "Rijk van Zanten"
}
}
}
To have a boiler template (example app code) would be great for new users using this package.
Hello, im trying your library, looks good and clean so far, but i met an issue.
Login is without a problem.
Logout has some troubles
calling this in service
Future<dynamic> logout() async {
Directus sdk = await Directus(API_ENDPOINT).init();
return await sdk.auth.logout();
}
in directus
22:06:09 ✨ request completed POST 401 /auth/refresh 7ms
im checking in main.dart if authEndpoint.isLoggedIn()
is false
but its true all the time.
seems like Authstorage removeLoginData
isnt cleared.
Hello,
I'm testing Directus Flutter and I come across this error when creating a user :
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
#0 new DirectusResponse package:directus/…/data_classes/directus_response.dart:16
#1 DirectusResponse.fromRequest package:directus/…/data_classes/directus_response.dart:44
I'm on the version :
directus: ^0.7.2
I'm on the latest version of flutter: 3.3.8
My code is:
final Directus sdk = await Directus(kEndpoint).init();
final DirectusResponse<DirectusUser> response = await sdk.users.createOne(
DirectusUser(
email: "[email protected]",
password: "password",
),
);
In backend, i use the latest version of "directus-project" (self hosted).
Is it a user error on my part, or a problem on the side of the response object
Hi
I'm trying to use your library to communicate with my Directus installation.
Flutter version: 2.2.3
OS: MacOS 11.2.3
Running your main.dart code, inside the example folder in this project I obtain this, upon running:
Restarted application in 845ms. [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value #0 MethodChannel.binaryMessenger package:flutter/…/services/platform_channel.dart:142 #1 MethodChannel._invokeMethod package:flutter/…/services/platform_channel.dart:148 #2 MethodChannel.invokeMethod package:flutter/…/services/platform_channel.dart:331 #3 MethodChannel.invokeMapMethod package:flutter/…/services/platform_channel.dart:358 #4 MethodChannelSharedPreferencesStore.getAll package:shared_preferences_platform_interface/method_channel_shared_preferences.dart:44 #5 SharedPreferences._getSharedPreferencesMap package:shared_preferences/shared_preferences.dart:180 #6 SharedPreferences.getInstance package:shared_preferences/shared_preferences.dart:56 #7 SharedPreferencesStorage.getItem package:directus/…/adapters/shared_preferences_storage.dart:14 #8 AuthStorage.getLoginData package:directus/…/auth/_auth_storage.dart:29 #9 AuthHandler.init package:directus/…/auth/auth_handler.dart:82 #10 Directus.init package:directus/src/directus.dart:56 #11 main package:redux_saga_beginner_tutorial/main.dart:8 #12 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:142:25) #13 _rootRun (dart:async/zone.dart:1354:13) #14 _CustomZone.run (dart:async/zone.dart:1258:19) #15 _runZoned (dart:async/zone.dart:1789:10) #16 runZonedGuarded (dart:async/zone.dart:1777:12) #17 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:138:5) #18 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19) #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
How to resolve this problem? Am I missing something?
Regards
Getting this error ⬇️
type 'String' is not a subtype of type 'int?' in type cast
while uploading file via 'uploadFile' method but it successfully uploads but throws error while parsing the response
My projects use custom authorization, this library does not allow me to add my own authorization.
Can we think of something?
I also want to organize this library!
Hello, first I would like to thank you for the package, it is very useful and well built!
I would like to know if there is a special reason for not using the 'Directus' class as a singleton, so I would keep the same instance to be recovered anywhere in the application.
I did a singleton on a project that I used your package to analyze and see if it would be interesting for the package.
The interesting thing about working with a singleton is that it would be possible to recover the same instance globally.
After init
I try to await ask.auth.login.....
but it never completes and code after it never execute not generate a user . for example the print("asf") will never run when I use the login await methode
Future<void> loginDirectus() async {
final sdk = await Directus('http://localhost:8055').init();
await sdk.auth
.login(email: "[email protected]", password: "A@12345678");
print("asf");
print("test");
var user = await sdk.auth.currentUser?.read();
print(user?.data);
}
fields.readOne throws an error saying 'List should use DirectusListResponse.'
I am not able to use typedItems in my application.
typedItems need a converter of type ItemsConverter which I can't import. Dart gives me warning when importing files from src folder.
Can you please add import 'package:directus/src/modules/items/items_converter.dart';
to directus.dart outside src folder? It would be really helpful.
By the way, thanks for such a helpful library 🙂
The below line throws an error: "Problem with Directus"
It should actually be converted to list like below
final mapData = data.map((item) => converter.toJson(item)).toList();
Currently it's hive
and sembast
.
Hive pros:
Hive cons:
Sembast pros:
Sembast cons:
Shared preferences are flutter only.
Secure flutter storage is flutter only, and without web.
I create custom user model extend DirectusUser and put phone field and try create user,
result :
import 'package:directus/directus.dart';
import 'package:json_annotation/json_annotation.dart';
class User extends DirectusUser {
String phone;
User({email, password, this.phone}) : super(email: email, password: password);
factory User.fromJson(Map<String, dynamic> json) => User(
phone: json["phone"],
email: json["email"],
password: json["password"],
);
}
...
final createdUser = sdk.users.createOne(User.fromJson(data));
Undefined binding(s) detected when compiling WHERE. Undefined column(s): [directus_users.phone] query: where "directus_users"."email" = ? or "directus_users"."phone" = ?
phone field not sended :/
Around 20 tests are now failing after switching to full null safety.
Hello,
thanks for this useful package! I have found a bug that occurs when directus does not send any data back in a response.
That happens when you set permissions for a role on a collection to create items, but not read items.
I am developing an app where you can take surveys anonymously. Because there is no personal identification, my users can create collection items but never read them. If I use the createOne method directus saves it in the database correctly and returns the 204 code.
Then a TypeError happens in your package, because no data is received:
E/flutter ( 6098): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
E/flutter ( 6098): #0 new DirectusResponse
package:directus/…/data_classes/directus_response.dart:16
E/flutter ( 6098): #1 DirectusResponse.fromRequest
package:directus/…/data_classes/directus_response.dart:44
If you need additional information I am happy to provide more. Thanks for your consideration.
That key would be used as a prefix for storage, so user can have multiple instances with auth at the same time
Would love to add a state management in built to handle streambuilder widget with stream determining whether the user is logged in or logged off.
This would give a realtime state management of the current user state. (Specially for determining whether to show login page or the main app)
The sdk.auth.logout() does not log out from the local authenticated user.
Once I use the logout() method and re-open the app, the previous user stays logged in :/
There is no simple way to use package without relaying on some sort of storage, and most of the storage options require a lot of boilerplate to set up. That's why hive
has hive
package and hive_flutter
. Why sembast
have sembast
and sembast_web
.
Or we can simply drop support for non flutter apps, since 99% of dart apps are Flutter apps?
Or we can create directus_base
that works without Flutter and directus
that works with Flutter?
It should reduce a lot of boilerplate, and it works with mockito
.
I removed lib
folder from example when adding generated files to git ignore
It looks like some data is nested, and most of the data is not top level.
Hello,
I am trying to deep filter my query like this deep[translations][_filter][languages_code][_eq]="en-US".
Unfortunately, the deep query parameter has to be of Map<String, Query>.
Is there any possibility to filter my subquery/relation?
The data structure is as follows
product -> translations
I tried to use Filter.relation but it returns both languages_codes.
My code looks like this:
await directusSdk.items('product').readMany(
query: Query(limit: 1, offset: 0, fields: ['sku', 'image', 'translations.*'] ),
filters: Filters({'and': Filter.and([
{'sku': Filter.eq(sku)},
{'translations': Filter.relation('languages_code', Filter.eq(languageCode))}
])})
);
Thank you for your help.
I am using the apstanisic/directus-dart version 0.9.5 and directus 9.23.1.
I have the following code when trying to filter by a DateTime field.
I have also tried using the string 'now' instead of manually creating a DateTime object.
final announcementsList = await sdk.items('announcements').readMany(
filters: Filters({
'and': Filter.and([
{
"date_effective": Filter.lte(
'${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}')
},
{
"date_expired": Filter.gte(
'${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}')
}
])
}));
Any insight would be appreciated. I would like to know if I am doing something wrong.
final response = await manuallyRefresh();
if (response?.accessToken != null) {
options.headers['authorization'] = 'Bearer ${response!.accessToken}';
} else {
options.headers.remove('authorization');
}
Refresh token interceptor wasn't working. After changing "Authorization" to "authorization" and prepending "Bearer " fixed the issue.
I've seen someone create an extension for the web panel and the backend, would love to see flutter firebase auth provider to work with this sdk.
I need every request add header device_code. Is it possible?
What happens with timeout when user exits, or is kills flutter app. There should be a way to check before each request if access token in expired
When logging back into an app after a refresh token has expired login should work correctly. The user should then be authenticated and be able to access data according to their role.
In the case of a renewal token that has expired, I'd expect the SDK to attempt to login using the usual method at the auth/login
endpoint.
When logging back into an app after a refresh token has expired login get's suck and the user is no longer able to log in at all. Even after calling:
sdk.auth.storage.removeLoginData();
ACCESS_TOKEN_TTL=1m
REFRESH_TOKEN_TTL=2m
sdk.auth.login(email: email, password: password)
note: clearing out the data from the app fixes the issue.
Building machine: Windows 10
Flutter Doctor output:
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.10, on Microsoft Windows [Version 10.0.19045.2486], locale en-NZ)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.4.2)
[√] Android Studio (version 2021.3)
[√] VS Code (version 1.74.3)
[√] Connected device (4 available)
[√] HTTP Host Availability
• No issues found!
directus sdk version: 0.9.3
Our testers have noticed that occasionally when trying to log in they'll get locked out of the app and we've worked out it's when the SDK is trying to use an expired renewal token. Since the default renewal token expiry is 7 days this only happens occasionally (until we set the expiry to much shorter).
Looks like the stored token is continued to be attempted and the login never reverts to the normal login methods, even after trying to clear out the stored user auth data.
I managed to add my custom fields. uitlaber@10c97a9 Now I can search through collections or other methods. And I can add the meta parameter but the problem get response.
https://docs.directus.io/reference/api/query/meta.html
I tried edit directus_list_response.dart
// ignore: import_of_legacy_library_into_null_safe
import 'package:dio/dio.dart';
import 'package:directus/src/modules/items/items_converter.dart';
import 'package:directus/src/modules/items/map_items_converter.dart';
import 'data_classes.dart';
/// Directus response object when data is [List].
///
/// When response is returning a [List] of items, use this instead of [DirectusRespones].
/// This class is created to properly and type safely convert data.
/// Using [List] respones inside [DirectusRespone] will throw an error. Only this
/// response should be used. It has all the same properties and methods,
/// but adopted when response is [List].
class DirectusListResponse<T> implements DirectusResponse<List<T>> {
/// Response data.
@override
late final List<T> data;
List<T>? meta;
/// Manually set data.
DirectusListResponse.manually(data) : data = data;
/// Constructor that converts Dio [Response] to [DirectusListResponse].
/// You can pass converter that is used to convert response [Map] to
/// proper object, by default it will return [Map].
DirectusListResponse(Response dioResponse, {ItemsConverter? converter}) {
converter ??= MapItemsConverter();
var data = dioResponse.data['data'];
var meta = dioResponse.data['meta'];
print(data);
if (!(data is List)) {
throw DirectusError(message: 'Data should be a list.');
} else {
this.data =
data.map((item) => converter!.fromJson(item)).cast<T>().toList();
}
if ((meta is List)) {
this.meta =
meta.map((item) => converter!.fromJson(item)).cast<T>().toList();
}
}
/// Static method that you can pass a closure that should return Dio [Response].
///
/// This will automaticaly convert [Response] to either [DirectusListResponse] or [DirectusError].
/// Most of the methods that return JSON object with key `data` that is [List]
/// should be called inside this method.
/// You can pass converter that is used to convert response [Map] to
/// proper object, by default it will return [Map].
static Future<DirectusListResponse<U>> fromRequest<U>(
Future<Response<dynamic>> Function() func, {
ItemsConverter? converter,
}) async {
converter ??= MapItemsConverter();
try {
final response = await func();
return DirectusListResponse<U>(response, converter: converter);
} on DioError catch (error) {
throw DirectusError.fromDio(error);
}
}
}
Dio client is stuck at sending request when using 4.0.4 version. If I remove first interceptor (DirectusSingleton.instance.client.interceptors.removeAt(0);
) it works properly. I don't know why 😕
It is working fine with Dio 4.0.0
Maybe there is a breaking change in Dio interceptor api
I was looking for Auth using static token . but sure it is supported yet
Code
final sdk = await Directus(config.API_URL).init();
try {
await sdk.auth.logout();
} catch (e) {
print(e);
}
Send to url POST /auth/refresh return status 401
But doesn't send anything POST /auth/logout
hey the new sdk switched the SDKs type signature was tweaked to make it consistent with the API's internal services. The .readMany method has been renamed to .readByQuery.
will this SDK receive an update to reflect this?
Hi, i have problem when filtering data
{
"data": [
{
"id": 6,
"status": "published",
"user_created": "46c84dc4-1340-4469-b580-3f8aa0a567be",
"date_created": "2021-01-08T11:33:33Z",
"user_updated": "46c84dc4-1340-4469-b580-3f8aa0a567be",
"date_updated": "2021-01-09T16:16:21Z",
"title": "Подарим второе дыхание Рыскуль апай",
"required_amount": "180000.00",
"collected_amount": "0.00",
"is_finished": false,
"indigent_id": null,
"video_url": null,
"fond_id": "46c84dc4-1340-4469-b580-3f8aa0a567be",
"photos": [
{
"id": 18,
"projects_id": 6,
"directus_files_id": "138c98fa-01f0-435f-8783-63a90681ab5b"
}
]
}
]
}
My query
final result = await sdk.items('projects').readMany(
query: Query(limit: 5, offset: 0, fields: ['*.*']),
filters: Filters({'is_finished': Filter.eq('false')})
);
result.data.forEach((project) => print(project['title']));
Take error
"filter" must be of type object
It would be awesome if this package could also be offered as a plain dart package. For example you can create your own packages in flutter and define there your API with this package and keeping the flutter root directory pristine.
If this package could natively enable/disable the persistent storage of data (caching the loaded data for offline usage) then it would change the game. (Just like firebase :3)
Hi ,
thanks for this awesome package,
please fix the method updateMany in items module , ( ids are now passed in data )
https://docs.directus.io/reference/items.html#update-multiple-items
Future<DirectusListResponse<T>> updateMany({required List<String> ids, required T data}) async {
if (ids.isEmpty) return DirectusListResponse.manually([]);
final mapData = converter.toJson({ 'keys': ids, 'data': data,});
return DirectusListResponse.fromRequest(
() =>
client.patch(
'$_endpoint',
data: mapData,
),
converter: converter,
);
}
It would be great if there could be a pagination feature while reading a collection.
P.S. I would love to contribute but since I'm a newbie here, help me understand how to contribute to this repo. Thanks!
Something like this below
contentType: MediaType.parse(mime(file.path)!)
Hey, it would be great if I could also contribute to this repo.
File download URL should return the whole download URL along with concatenated auth token of the current user
The Interceptor used for refreshing the token has an unhandled exception. It happens when the server gives error 401 on an invalid refresh token.
Here's the interceptor
Future<void> refreshExpiredTokenInterceptor(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
...
final response = await manuallyRefresh();
if (response?.accessToken != null) {
options.headers['Authorization'] = response!.accessToken;
} else {
options.headers.remove('Authorization');
}
return handler.next(options);
}
Here's the method that throws the exception.
Future<AuthResponse?> manuallyRefresh() async {
...
try {
...
} catch (e) {
client.unlock();
throw DirectusError.fromDio(e);
}
...
}
I think it should handle the logout automatically after an invalid refresh token.
It would be nice to have direct access to Dio in order to use custom endpoints in Directus.
btw. Great project!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.