Giter Site home page Giter Site logo

supabase / supabase-flutter Goto Github PK

View Code? Open in Web Editor NEW
624.0 28.0 148.0 1.45 MB

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.

Home Page: https://supabase.com/

License: MIT License

Dart 89.63% Kotlin 0.02% Ruby 0.44% Swift 0.27% Objective-C 0.01% CMake 2.96% C++ 3.53% C 0.23% HTML 0.30% PLpgSQL 2.44% Dockerfile 0.18%
dart-package postgres websocket flutter mobile-development realtime database mit-license supabase

supabase-flutter's Introduction

Supabase

Supabase Flutter

Flutter Client library for Supabase.

Run locally

This repo is a monorepo powered by Melos containing supabase_flutter and its sub-libraries. All packages are located in the packages directory.

To install on a locally developed app:

  • Clone this repo
  • Install Melos globally if you haven't already: dart pub global activate melos
  • Run melos bootstrap or melos bs at the root of the cloned directory to install dependencies
  • Add the target package to your pubspec.yaml file specifying the path.
    supabase_flutter:
      path: <your-path-to-the-local-supabase-flutter-repo>/packages/supabase_flutter

Contributing

  • Fork the repo on GitHub
  • Clone the project to your own machine
  • Commit changes to your own branch
  • Push your work back up to your fork
  • Submit a Pull request so that we can review your changes and merge

License

This repo is licenced under MIT.

Resources

supabase-flutter's People

Contributors

auxx avatar bdlukaa avatar bohan0 avatar borgoat avatar danmossa avatar dshukertjr avatar dsyrstad avatar gabfeudo avatar hwr12 avatar jocubeit avatar kaboc avatar kiwicopple avatar kyleparker-gongyuan avatar lucasxu0 avatar musaddiq625 avatar ozasadnyy avatar phamhieu avatar point-source avatar ramirond avatar rickypid avatar roneylf avatar seenickcode avatar spydon avatar sugitlab avatar techcomet avatar tommylcox avatar tylandercasper avatar vanethos avatar vhanda avatar vinzent03 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  avatar  avatar  avatar

supabase-flutter's Issues

error=server_error&error_description

when i log in with facebook with another account i get an error

"error=server_error&error_description=Error+getting+user+email+from+external+provider#="

and I comply with all the steps that are in the supabase guide
I use the same sample code that you provide to the documentation

auth.signIn without email confirmation is not redirecting automatically after being authenticated

Bug report

auth.signIn without email confirmation does not redirect automatically after being authenticated

Describe the bug

onAuthenticated and onUnauthenticated overrides did not detect changes after signIn/signUp. So I currently rely on

supabase.auth.onAuthStateChange((event, session) {
      if (event == AuthChangeEvent.signedIn) {
        
      }
    });

to detect for auth change

A clear and concise description of what the bug is.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to '…'
  2. Click on '…'
  3. Scroll down to '…'
  4. See error

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS:Windows
  • Browser: chrome
  • Version of supabase_flutter: 0.2.8

Additional context

Add any other context about the problem here.

Forget password UI

Forget password web UI

Currently, forget password sends a reset email but not has a firebase like a web UI to enter a new password and conform it.

After the user click on the reset password link in the email,
we shall direct to a site where the user can enter a new password.

Array being passed as String ("[]") in realtime event

Hi, I have an array field as one of my columns. When the realtime gets the inserted event and the array is empty my payload.newRecord contains an empty array as string ("[]") and not the array itself. I think it wasn't this way before because my code was working and now I tested and it's breaking. Using the latest version of supabase.

I don't know if it's a real issue or it'll be that way from now on.

Updating data returns an empty Exception when there is no results returned

Take the following function as an example:

  @override
  Future<void> markNotificationsAsSeen() async {
    final res = await supabaseClient
        .from('notifications')
        .update({'is_seen': true}, returning: ReturningOption.minimal)
        .eq('notified_uid', supabaseClient.auth.currentUser!.id)
        .eq('is_seen', false) // <~~~ commenting this out makes the error disappear
        .execute();
    if (res.hasError) {
      throw Exception(res.error);
    }
  }

When all notifications for the given notified_uid are already false (i.e. no result is returned), I get the following exception:

Exception: PostgrestError(message: [], code: null, details: null, hint: null)

I was able to confirm this in several ways:

  • commenting out .eq('is_seen', false) -- no issue
  • Manually changing a single notification's is_seen to false on Dashboard -- no issue on the first call, error appears in subsequent ones.
  • I ran the query on the Dashboard -- no issues.

Given that, I assume the error is caused when no results are returned.

Version:

  • supabase: ^0.2.13
  • flutter: 2.8.1

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String?' in type cast

I'm encountering an unexpected error when subscribing to realtime database changes and I couldn't find anything about it on the web.

...
final supabase = Supabase.instance;
...

class User {
  String uid;
  late final RealtimeSubscription subscription;

  User({required this.uid}) {
    subscription = supabase.client.from("profiles:id=eq.$uid").on(SupabaseEventTypes.update, (data) {
      stdout.writeln("Updating user $uid");
    });
  }
}

The subscription works flawlessly for the first ~30 seconds but then stops working with the following error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String?' in type cast
#0      RealtimeSubscription.onError.<anonymous closure> (package:realtime_client/src/realtime_subscription.dart:97:42)
#1      RealtimeSubscription.trigger (package:realtime_client/src/realtime_subscription.dart:225:20)
#2      RealtimeClient.onConnMessage.<anonymous closure>.<anonymous closure> (package:realtime_client/src/realtime_client.dart:267:34)
#3      Iterable.forEach (dart:core/iterable.dart:279:35)
#4      RealtimeClient.onConnMessage.<anonymous closure> (package:realtime_client/src/realtime_client.dart:266:60)
#5      new RealtimeClient.<anonymous closure> (package:realtime_client/src/realtime_client.dart:88:21)
#6      RealtimeClient.onConnMessage (package:realtime_client/src/realtime_client.dart:251:11)
#7      RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:110:11)
#8      _rootRunUnary (dart:async/zone.dart:1434:47)
#9      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#10     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#12     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#13     _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
#14     _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10)
#15     _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
#16     _rootRunUnary (dart:async/zone.dart:1434:47)
#17     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#22     _StreamController._add (dart:async/stream_controller.dart:607:7)
#23     _rootRunUnary (dart:async/zone.dart:1434:47)
#24     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#25     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#26     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#27     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#28     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#29     _StreamController._add (dart:async/stream_controller.dart:607:7)
#30     _StreamController.add (dart:async/stream_controller.dart:554:5)
#31     new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1144:21)
#32     _rootRunUnary (dart:async/zone.dart:1434:47)
#33     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#34     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#35     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#36     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#37     _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)
#38     _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)
#39     _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:332:23)
#40     _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:226:46)
#41     _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)
#42     _rootRunUnary (dart:async/zone.dart:1434:47)
#43     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#44     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#45     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#46     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#47     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#48     _StreamController._add (dart:async/stream_controller.dart:607:7)
#49     _StreamController.add (dart:async/stream_controller.dart:554:5)
#50     _Socket._onData (dart:io-patch/socket_patch.dart:2303:41)
#51     _rootRunUnary (dart:async/zone.dart:1434:47)
#52     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#53     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#54     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#55     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#56     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#57     _StreamController._add (dart:async/stream_controller.dart:607:7)
#58     _StreamController.add (dart:async/stream_controller.dart:554:5)
#59     _RawSecureSocket._sendReadEvent (dart:io/secure_socket.dart:1000:19)
#60     _rootRun (dart:async/zone.dart:1418:47)
#61     _CustomZone.run (dart:async/zone.dart:1328:19)
#62     _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
#63     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
#64     _rootRun (dart:async/zone.dart:1426:13)
#65     _CustomZone.run (dart:async/zone.dart:1328:19)
#66     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1260:23)
#67     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#68     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19)
#69     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5)
#70     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)

I'm running Windows 10 (Win32 app), supabase-flutter 0.2.11.

Not able to import CountOptions enum

Bug report

Describe the bug

Not able to import CountOptions enum.
When clicking the Quick Fix in VS Code, it only showing create class, local variable and mixin.
It is not showing the library to import.

To Reproduce

await supabase
          .from(tableName)
          .select()
          .eq(column, value)
          .execute(count: CountOptions.exact);

Screenshots

image
image

System information

  • OS: Ubuntu 20.04
  • Version of supabase_flutter: 0.2.8
  • Version of flutter: 2.5.1

The authenticated user get logout after a hour

Authentication Bug

If user is not connected to internet and open app after a hour or two, the supabase.auth.user is null so the app show the login screen to user again.

To Reproduce

  1. Run the quick start example
  2. Close the app
  3. Open app after hour or two with no internet connection
  4. The supabase.auth.user which is current user will be null

signIn not returning data from future

Bug report

Describe the bug

I have written a register function that makes the signUp call and either reports an error or sends the user to the login page.

  Future _register() async {
    final result = await supabase.auth.signUp(_emailController.text, _passwordController.text);

    final user = result.data?.user;
    final error = result.error;
    logger.d('result: ', result.rawData);
    logger.d('user: ', user);
    logger.d('error: ', error);
    
    if (user != null) {
      Navigator.pushReplacementNamed(context, '/login');
      _showDialog(context, title: 'Success', message: 'Register Successful');
    } else if (error != null) {
      _showDialog(context, title: 'Error', message: error.message);
    } else {
      _showDialog(context, title: 'Error', message: 'Something weird happened');
    }
  }

This is based on the documentation here: https://supabase.com/docs/reference/dart/auth-signin.

This logs the following.

flutter: ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: │ #0   _RegisterViewState._register
flutter: │ #1   <asynchronous suspension>
flutter: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
flutter: │ 🐛 result:
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: │ #0   _RegisterViewState._register
flutter: │ #1   <asynchronous suspension>
flutter: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
flutter: │ 🐛 user:
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: │ #0   _RegisterViewState._register
flutter: │ #1   <asynchronous suspension>
flutter: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
flutter: │ 🐛 error:
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

The code always falls through to the else block.

I know that the HTTP call is working as expected. I have ProxyMan reporting the req/resp and it all looks good there.

To Reproduce

Add the above code to a function in a class extending AuthState, and use it to perform registration.

Expected behavior

I expect to receive non-null data from the reponse.

System information

  • OS: iOS
  • Browser: NA
  • Version of supabase-flutter: ^0.2.9

Latest posgres update breaks querying with or filter

Bug report

Using supabase-dart to query a table using filters but it returns null.
Supabase team reverted the recent postgres upgrade and everything works now.

Reproduce:

Query table:

supaBaseClient
        .from('posts')
        .select()
        .or("blocked_ids.eq.$userId, blocked_ids.is.NULL");

Error:

PostgrestError(message: "failed to parse logic tree ((blocked_ids.eq.6, blocked_ids.is.NULL))" (line 1, column 23), code: null, details: unexpected "n" expecting "or", hint: null)

plugin version:

supabase: ^0.2.8

Session not stored with the latest supabase_flutter update

supabase_flutter v 0.2.1

I curreny following the supabase flutter quickstart tutorial https://supabase.io/docs/guides/with-flutter.

Here is my link to the project - https://github.com/sumchans/Bol

I haven't made any drastic changes to the tutorial, all I have worked on is the login_page.dart

The issue is -

  1. A user signs up or signs in with phone.
  2. The user closes and then reopens the app
  3. The user is directed to the sign in screen.

Expected result - The user should be automatically signed in with the session information currently on device.

Testing this project on the iOS simulator.

Running this code print null for response.

    final response = await supabase.auth.signIn(phone: _phoneNumber);
    print(response.data);

Unhandled Exception: HiveError: Box not found. Did you forget to call Hive.openBox()?

Getting that when starting my app with the newest version.

Not sure when it started occurring, but has anyone ever seen that issue?
Thanks

I/flutter ( 7419): ***** Supabase init completed Instance of 'Supabase'
I/flutter ( 7419): ***** SupabaseAuthState startAuthObserver
I/flutter ( 7419): ***** SupabaseDeepLinkingMixin startAuthObserver
I/flutter ( 7419): ***** SupabaseAuthState startAuthObserver
I/flutter ( 7419): ***** SupabaseDeepLinkingMixin startAuthObserver
E/flutter ( 7419): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: HiveError: Box not found. Did you forget to call Hive.openBox()?

Difficult to mock Supabase auth

Feature request

Is your feature request related to a problem? Please describe.

Most Flutter apps use only supabase provider auth (i.e. google, in my case). When I want to integration test my app, sadly Flutter cannot interact with web views. Therefore, I am forced to simulate a supabase user session.

What I am doing now is: 1) mocking Supabase when I perform queries and 2) mock Supabase login. The former is pretty straightforward, as I mock a "repository" that wraps interaction with Supabase queries. But my question to the team is that for the latter, it seems messy, with this library, to mock Supabase auth because it seems that if I want to implement my own mock method overrides for SupabaseAuthState, such as onAuthenticated, etc, I have to inject a mock "State" widget into my app.

Describe the solution you'd like

A cleaner way to listen to Supabase auth events. Maybe with a Stream or expose some observer? Overall, it seems that assuming the user will want to override Supabase auth events in the state widget may be too confining and not testing friendly.

I propose that either some integration testing examples are developed in the existing examples provided for supabase_flutter or we discuss some options.

Describe alternatives you've considered

Here's an example of what I am doing now re integration tests and having to inject a mock State widget that extends SupabaseAuthState.

Stream doesn’t not work for some tables

My Stream doesn't update the data for a table but for all others tables , it work

That's the code for listening

void _loaddata () {
  Supabase.instance.from("test").stream.execute().listen((Event){
    print(Event);
  });
  
  Supabase.instance.from("test1").stream.execute().listen((Event){
    print(Event);
  });
  
  Supabase.instance.from("test2").stream.execute().listen((Event){
    print(Event);
  });
}

I get real time changes from table test1 and test2 but not from table test .

Native Sign In

Feature request

Is your feature request related to a problem? Please describe.

I want to sign in using a sign in provider, but the current implementation is not good. Launching the browser is not a good user experience.

Describe the solution you'd like

Use the google_sign_in package to sign the user in using Google and sign_in_with_apple to sign the user in using Apple.

Both of the packages return the user credentials, so, if I could sign in using the user credentials (just like Firebase does), it'd be great!

Aditional context

If launching the brower will still be the current solution, we could have in-app-handling.
By default, Android opens up a browser when handling URLs. You can pass forceWebView: true parameter to tell the plugin to open a WebView instead.

Support for Desktop

Currently I get a platform exception trying to use this in a flutter app deployed to windows.
Are there any plans to extend support to desktop?

Thanks!

flutter_supabase auth.signOut() should trigger 'onUnauthenticated'

Feature request

Is your feature request related to a problem? Please describe.

It would be ideal to keep all auth state logic in a single place, such as here, but unfortunately, when calling signOut, nothing in this AuthState implementation gets triggered, thus making the user's code brittle, because we have to code logic like this to update the route stack, vs having it all done in our AuthState implementation.

Update supabase dependency to fix RealtimeSubscription Unhandled Exception: type 'Null' is not a subtype of type 'List<dynamic>' in type cast

I'm running version 0.2.9 of supabase_flutter and started to get this error in my realtime, I think this is related to this issue that is already resolved. Can the supabase_flutter be upgraded to use 0.2.10 version of supabase?

Error: Expected a value of type 'List<dynamic>', but got one of type 'Null'
    at Object.throw_ [as throw] (http://localhost:56672/dart_sdk.js:5061:11)
    at Object.castError (http://localhost:56672/dart_sdk.js:5020:15)
    at Object.cast [as as] (http://localhost:56672/dart_sdk.js:5345:17)
    at Function.as_C [as as] (http://localhost:56672/dart_sdk.js:4966:19)
    at WhereIterator.new.<anonymous> (http://localhost:56672/packages/supabase/src/supabase_realtime_payload.dart.lib.js:86:93)
    at WhereIterator.new.moveNext (http://localhost:56672/dart_sdk.js:23320:56)
    at MappedIterator.new.moveNext (http://localhost:56672/dart_sdk.js:23200:30)
    at JsIterator.next (http://localhost:56672/dart_sdk.js:6813:21)
    at Function.of (http://localhost:56672/dart_sdk.js:44586:18)
    at MappedIterable.__.toList (http://localhost:56672/dart_sdk.js:21359:30)
    at Function.fromJson (http://localhost:56672/packages/supabase/src/supabase_realtime_payload.dart.lib.js:86:280)
    at realtime_subscription.Binding.new.<anonymous> (http://localhost:56672/packages/supabase/src/supabase_realtime_client.dart.lib.js:48:83)
    at realtime_subscription.RealtimeSubscription.new.trigger (http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:494:12)
    at http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:918:145
    at WhereIterable.new.forEach (http://localhost:56672/dart_sdk.js:21308:11)
    at http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:918:117
    at realtime_client.RealtimeClient.new.<anonymous> (http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:1038:81)
    at realtime_client.RealtimeClient.new.onConnMessage (http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:923:12)
    at http://localhost:56672/packages/realtime_client/src/push.dart.lib.js:782:16
    at _RootZone.runUnaryGuarded (http://localhost:56672/dart_sdk.js:38448:11)
    at _ControllerSubscription.new.[_sendData] (http://localhost:56672/dart_sdk.js:32328:22)
    at _ControllerSubscription.new.[_add] (http://localhost:56672/dart_sdk.js:32277:26)
    at _SyncStreamController.new.[_sendData] (http://localhost:56672/dart_sdk.js:35152:34)
    at _SyncStreamController.new.[_sendData] (http://localhost:56672/dart_sdk.js:35256:32)
    at _SyncStreamController.new.[_add] (http://localhost:56672/dart_sdk.js:34966:26)
    at _SyncStreamController.new.add (http://localhost:56672/dart_sdk.js:34932:19)
    at _RootZone.runUnaryGuarded (http://localhost:56672/dart_sdk.js:38448:11)
    at _ControllerSubscription.new.[_sendData] (http://localhost:56672/dart_sdk.js:32328:22)
    at _ControllerSubscription.new.[_add] (http://localhost:56672/dart_sdk.js:32277:26)
    at _SyncStreamController.new.[_sendData] (http://localhost:56672/dart_sdk.js:35152:34)
    at _SyncStreamController.new.[_sendData] (http://localhost:56672/dart_sdk.js:35256:32)
    at _SyncStreamController.new.[_add] (http://localhost:56672/dart_sdk.js:34966:26)
    at _SyncStreamController.new.add (http://localhost:56672/dart_sdk.js:34932:19)
    at _StreamSinkWrapper.new.add (http://localhost:56672/dart_sdk.js:35290:24)
    at _GuaranteeSink.new.add (http://localhost:56672/packages/stream_channel/src/stream_channel_controller.dart.lib.js:1120:24)
    at http://localhost:56672/packages/web_socket_channel/src/copy/web_socket_impl.dart.lib.js:1333:37
    at Object._checkAndCall (http://localhost:56672/dart_sdk.js:5268:16)
    at Object.dcall (http://localhost:56672/dart_sdk.js:5273:17)
    at WebSocket.<anonymous> (http://localhost:56672/dart_sdk.js:101824:100)

Downloading and uploading progress

When we upload or download a file
I need to get the progress of downloading or uploading

For example:
supabase.storage.from('avatars').download(path)

Shall give me the progress of downloading

nested StreamBuilder bug report (using supabase: ^0.2.8 on Flutter project)

Bug report

nested StreamBuilder bug report (using supabase: ^0.2.8 on Flutter project)

Describe the bug

A clear and concise description of what the bug is.
I have the same Flutter project running on Firebase with nested StreamBuilders and it works very well and response immediately and correctly when I insert or update data to the Firebase. But when I transfer my Flutter project to Supabase, it works well and I found that Supabase is the good choice for migrating from Firebase to Supabase with RDBS. So I did more tests for my Flutter project on Supabase (which are the same actions running on Firebase), but I found the streams sometimes repose good but sometimes not work.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:
Here are my code snippets:
截圖 2021-10-22 上午11 30 25

  1. Go to '…'
  2. Click on '…'
  3. Scroll down to '…'
  4. See error
    There are two tables in the database and I use nested StreamBuilder to get data from each table.
    When I added the data to 'the first table - owners' the two streams work correctly, but when I added the data to 'the second table - projects' the streams no reaction even the data was really insert to the second table successfully (I checked the Supabase admin console).

here is the error data:
<img width="1231" alt="截圖 2021-10-22 上午10 57 43" src="https://user-images.githubuserco
截圖 2021-10-22 上午10 58 24
ntent.com/81674344/138389231-5949a346-4778-4d5d-8226-529557035395.png">
截圖 2021-10-22 上午10 58 36

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.
Just like what I get from Firebase with nested StreamBuilders for fetching data from database immediately and correctly.
The stream should response immediately and correctly when I insert or do any action to my database so that I can doing the correct operation for my project and database.

System information

  • OS: macOS Big Sur 11.6
  • Browser chrome
  • version of supabase: supabase: ^0.2.8
  • Flutter 2.5.3 with Dart version 2.14.4
  • Version of supabase-js: N/A
  • Version of Node.js: N/A

截圖 2021-10-22 上午11 30 52

## Additional context

Add any other context about the problem here.

Signup: Response is empty for EmailValidation

Bug report

When using signup(username, password) the response object fetched has all its values as null. This is apparently supposed to indicate that the user now needs to validate the email. This is super cryptic, and took me some time to figure out.

To Reproduce

var auth = Supabase.instance.client.auth;
var result = await auth.signUp(
    '[email protected]',
    'hellohello',
    options: AuthOptions(redirectTo: 'gitjournal-identity://callback'),
  );
  print(result);
  if (result.data != null) {
    print('result not null');
    print('done?');
  }
  print('data: ${result.data}');
  print('rawData: ${result.rawData}');
  print('user: ${result.user}');
  print('url: ${result.url}');
  print('provider: ${result.provider}');
  print('Error: ${result.error}');
  print('Error Message: ${result.error?.message}');
},
flutter: Instance of 'GotrueSessionResponse'
flutter: data: null
flutter: rawData: null
flutter: user: null
flutter: url: null
flutter: provider: null
flutter: Error: null
flutter: Error Message: null

Expected behavior

Some easy way of figuring out that email validation is now required. One option would be to add a bool emailValidationRequired in the GotrueSessionResponse. Please let me know what solution would be acceptable.

I might / might-not provide a PR once the solution is agreed on. I don't want to commit myself.

Bug in auth state

Initially auth.currentUser return null even after successfully logged in, after a few milliseconds auth.currentUser return the user;

MaterialApp(
  ...
  home: auth.currentUser == null ? const LoginPage() : const HomePage() 
// Always returns `LoginPage()` initially but after hot reload, it returns `HomePage()`
  ...
)

Crash when re-logging in after signing out (w/ Google provider)

Bug report

Describe the bug

So I am using signInWithProvider + Google successfully, mainly using the example code provided here to implement a splash screen with SupabaseAuthState to receive auth events. The problem I have is that when I log out using Supabase.instance.client.auth.signOut(), then try to log in again, an exception is thrown.

Here's the error:

PlatformException (PlatformException(Error, Error while launching https://<redacted>.supabase.co/auth/v1/authorize?provider=google&redirect_to=com.manninglabs.steadycalendar%3A%2F%2Flogin-callback%2F, null, null))

Here's the stack trace.

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: PlatformException(Error, Error while launching https://<redacted>.supabase.co/auth/v1/authorize?provider=google&redirect_to=com.manninglabs.steadycalendar%3A%2F%2Flogin-callback%2F, null, null)
#0      StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:607
#1      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:156
<asynchronous suspension>
#2      launch
package:url_launcher/url_launcher.dart:101
<asynchronous suspension>
#3      GoTrueClientSignInProvider.signInWithProvider
package:supabase_flutter/src/supabase_auth.dart:170
<asynchronous suspension>
#4      LoginOptions._signupTapped
package:lesson02/…/login_options/login_options.dart:45
<asynchronous suspension>

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Run the app
git clone [email protected]:seenickcode/fluttercrashcourse-lessons.git
git clone -b troubleshooting-relogin-crash 
git checkout --track origin/troubleshooting-relogin-crash
cd module03-steadycalendar/lesson02
flutter run

Ensure app runs in a simulator/emulator.

  1. Tap "Get Started", then "Continue with Google", a webview will appear, sign in with any Google account, tap "Done" to dismiss the webview after signing in (required to maybe a bug on the iOS simulator? not clear if it's supabase_flutter)

  2. Now tap "Log Out", tap "Get Started", then "Continue with Google", a webview will appear.

  3. At this point, the (app will crash) (see stacktrace I mentioned above)

  4. Expected behavior

No crashes when re-attempting to login.

System information

  • OS: iOS simulator (iOS 15.0)
  • Version of flutter_supabase: ^0.2.9

Context

Migrate To Null Safety

Need migrate to null safety

Is your feature request related to a problem? Please describe.

Now Flutter new project by default using with null safety. To use it in a broad manner with a large audience, we need to migrate it to null safety.

Describe the solution you'd like

Anybody can fork it, migrate to the null safety, and can send a pull request

Describe alternatives you've considered

Mentioned Above

Additional context

Null safety addition will be a good addition for current flutter projects

Closing web view when `url_launcher` is finished?

Feature request

Is your feature request related to a problem? Please describe.

It seems that when, say, authenticating with the Google provider, a webview opens using the Flutter url_launcher package. Users must then call await closeWebView(); when the onAuthenticated() hook is called for SupabaseAuthState.

Describe the solution you'd like

Guidance on if this is the correct way to do dismiss the webview after a provider login. Ideally, a dev friendly method of dismissing it without using the above solution.

Error when listening to realtime events

Bug report

Describe the bug

Sometimes when I'm subscribed to a table in my database and reveive new events I got this error, but couldn't find the reason to it. Any tips where to search?

E/flutter ( 4940): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Concurrent modification during iteration: Instance(length:18) of '_GrowableList'.
E/flutter ( 4940): #0      ListIterator.moveNext (dart:_internal/iterable.dart:336:7)
E/flutter ( 4940): supabase/supabase-flutter#1      WhereIterator.moveNext (dart:_internal/iterable.dart:438:22)
E/flutter ( 4940): supabase/supabase-flutter#2      Iterable.forEach (dart:core/iterable.dart:279:23)
E/flutter ( 4940): supabase/supabase-flutter#3      RealtimeClient.onConnMessage.<anonymous closure> (package:realtime_client/src/realtime_client.dart:264:60)
E/flutter ( 4940): supabase/supabase-flutter#4      new RealtimeClient.<anonymous closure> (package:realtime_client/src/realtime_client.dart:86:21)
E/flutter ( 4940): supabase/supabase-flutter#5      RealtimeClient.onConnMessage (package:realtime_client/src/realtime_client.dart:249:11)
E/flutter ( 4940): supabase/supabase-flutter#6      RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:108:11)
E/flutter ( 4940): supabase/supabase-flutter#7      _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#8      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4940): supabase/supabase-flutter#9      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4940): supabase/supabase-flutter#10     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 4940): supabase/supabase-flutter#11     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter ( 4940): supabase/supabase-flutter#12     _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter ( 4940): supabase/supabase-flutter#13     _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10)
E/flutter ( 4940): supabase/supabase-flutter#14     _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
E/flutter ( 4940): supabase/supabase-flutter#15     _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#16     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4940): supabase/supabase-flutter#17     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4940): supabase/supabase-flutter#18     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 4940): supabase/supabase-flutter#19     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter ( 4940): supabase/supabase-flutter#20     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
E/flutter ( 4940): supabase/supabase-flutter#21     _StreamController._add (dart:async/stream_controller.dart:607:7)
E/flutter ( 4940): supabase/supabase-flutter#22     _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#23     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4940): supabase/supabase-flutter#24     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4940): supabase/supabase-flutter#25     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 4940): supabase/supabase-flutter#26     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter ( 4940): supabase/supabase-flutter#27     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
E/flutter ( 4940): supabase/supabase-flutter#28     _StreamController._add (dart:async/stream_controller.dart:607:7)
E/flutter ( 4940): supabase/supabase-flutter#29     _StreamController.add (dart:async/stream_controller.dart:554:5)
E/flutter ( 4940): supabase/supabase-flutter#30     new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1150:21)
E/flutter ( 4940): supabase/supabase-flutter#31     _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#32     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4940): supabase/supabase-flutter#33     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4940): supabase/supabase-flutter#34     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 4940): supabase/supabase-flutter#35     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter ( 4940): supabase/supabase-flutter#36     _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)
E/flutter ( 4940): supabase/storage-dart#16     _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)
E/flutter ( 4940): supabase/supabase-flutter#38     _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
E/flutter ( 4940): supabase/supabase-flutter#39     _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
E/flutter ( 4940): supabase/supabase-flutter#40     _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)
E/flutter ( 4940): supabase/supabase-flutter#41     _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#42     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 4940): supabase/supabase-flutter#43     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 4940): supabase/supabase-flutter#44     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 4940): supabase/supabase-flutter#45     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter ( 4940): supabase/supabase-flutter#46     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
E/flutter ( 4940): supabase/supabase-flutter#47     _StreamController._add (dart:async/stream_controller.dart:607:7)
E/flutter ( 4940): supabase/supabase-flutter#48     _StreamController.add (dart:async/stream_controller.dart:554:5)
E/flutter ( 4940): supabase/supabase-flutter#49     _Socket._onData (dart:io-patch/socket_patch.dart:2166:41)
E/flutter ( 4940): supabase/supabase-dart#64     _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter ( 4940): supabase/supabase-flutter#51     _CustomZone.runUnary (dart:async/zone.d

Running the last version of supabase_flutter

email authentication example code has small mistake.

Improve documentation

Link

https://github.com/supabase/supabase-flutter#email-authentication

Describe the problem

In your example code, you use underscore _email and _password, but parameters doesn't have the underscore.

import 'package:supabase_flutter/supabase_flutter.dart';

void signIn(String email, String password) async {
  final response = await Supabase.instance.client.auth.signIn(email: _email, password: _password);
  if (reponse.error != null) {
    /// Handle error
  } else {
    /// Sign in with success
  }
}

Describe the improvement

Please remove underscore. It looks using private var.

Additional context

no more additional context.

A simple app for real-time chat

A simple app for real time chat with a group of users and single users
With caching and realtime features to well learn that supabase can help us.

Flutter Deeplink İssue

Bug report

Flutter Deeplink İssue

Describe the bug

I do social login with Flutter, but after login it doesn't return to the application. I make all the adjustments as shown in the docs but it fails. The error may be caused by me, because I downloaded the Supabase demo application and tried it, there is the same problem.
A clear and concise description of what the bug is.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to '…'
  2. Click on '…'
  3. Scroll down to '…'
  4. See error

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. chrome, safari]
  • Version of supabase-js: [e.g. 6.0.2]
  • Version of Node.js: [e.g. 10.10.0]

Additional context

Add any other context about the problem here.

Recovery session should happen automatically

Bug report

Describe the bug

Right now recovery session is not called under Supabase.initialize which is bad because users won't have access to session, user on app start

Expected behavior

User should be able to access user and session after Supabase.initialize if there is persisted session info.

Additional context

Related #10

Sharedpreferences doesn't work on IOS

When I sign in, I can see the session, but when I restart the application

client.auth.session()
client.auth.user()
client.auth.currentUser

all values return null.

Flutter Web Login

Hi there,
I am trying to integrate Supabase with the flutter App. I am using plugin url_strategy to remove # from the flutter URL.
https://pub.dev/packages/url_strategy/

But when I get Supabase call back it starts with # so the flutter web router also removes that URL. Is there any we can get call back URL without #?

Cannot run multiple Instances of Supabase Windows Desktop App

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a simple app and Initialize supabase app.
  2. Build a release of the app.
  3. Run 2 Instance of The app

The issue is that Supabase use a single file which Is reading by the first Instance so the second Instance of the app is not working.

Slow responses from queries

Bug report

Describe the bug

When doing queries or even sign in, on a desktop app (havent tried with flutter web), the responses are very very slow
taking about ~5 seconds each.

To Reproduce

for example even a simple query as

supabase.client.from('collections').select().execute().then((response) {
  ...
}

is very slow, for example running 2-3 times i got a response after 5 seconds

i dont know if it has to do with cold start, but it seems even after i send multiple requests,
some times it responses fast and some the casual 5seconds

supabase

Expected behavior

Afterwards i tested with a newly created project, with js and everything was running smoothly,
both servers are located at eu-central-1.

In the browser (pure js) it run like instant, but on the desktop version gives a very bad experience

System information

flutter doctor -v:

[✓] Flutter (Channel unknown, 2.2.1, on Linux, locale en_US.UTF-8)
• Flutter version 2.2.1 at /home/paradox11/fvm/versions/2.2.1
• Framework revision 02c026b03c (2 months ago), 2021-05-27 12:24:44 -0700
• Engine revision 0fdb562ac8
• Dart version 2.13.1

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /home/paradox11/Android/Sdk
• Platform android-30, build-tools 30.0.3
• Java binary at: /home/paradox11/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.8+0-b944-P17168821)
• All Android licenses accepted.

[✓] Chrome - develop for the web
• CHROME_EXECUTABLE = /usr/bin/google-chrome-stable

[✓] Linux toolchain - develop for Linux desktop
• clang version 12.0.1
• cmake version 3.21.1
• ninja version 1.10.2
• pkg-config version 0.29.2

[✓] Android Studio (version 2020.3)
• Android Studio at /home/paradox11/android-studio
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.8+0-b944-P17168821)

[✓] Android Studio
• Android Studio at /opt/android-studio
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.8+0-b944-P17168821)

[✓] Connected device (2 available)
• Linux (desktop) • linux • linux-x64 • Linux
• Chrome (web) • chrome • web-javascript • Google Chrome 91.0.4472.77

• No issues found!

supabase plugins:

supabase_flutter: 0.0.8
supabase: 0.0.8

Provide documentation for running tests locally

Attempting to run tests locally fail.

This seems to be because the tests require a docker container running as well as an .env file that configures the tests. We should provide documentation to help contributors run tests locally.

Test output without any changes after cloning:

dart test
Building package executable... (4.1s)
Built test:test.
00:01 +0: loading test/provider_test.dart                                                                                                                                                                        [dotenv] Load failed: file not found: File: '.env'
00:02 +3 -1: test/provider_test.dart: (setUpAll) [E]                                                                                                                                                             
  Null check operator used on a null value
  test/provider_test.dart 23:23  main.<fn>
  
00:02 +3 -2: test/client_test.dart: client signUp() [E]                                                                                                                                                          
  Expected: null
    Actual: 'SocketException: OS Error: Connection refused, errno = 61, address = localhost, port = 63276'
  
  package:test_api            expect
  test/client_test.dart 52:7  main.<fn>.<fn>
  
00:02 +3 -3: test/client_test.dart: client signIn() [E]                                                                                                                                                          
  Expected: null
    Actual: 'SocketException: OS Error: Connection refused, errno = 61, address = localhost, port = 63278'
  
  package:test_api            expect
  test/client_test.dart 63:7  main.<fn>.<fn>
  
00:02 +3 -4: test/client_test.dart: client Get user [E]                                                                                                                                                          
  Expected: <Instance of 'String'>
    Actual: <null>
     Which: is not an instance of 'String'
  
  package:test_api             expect
  test/client_test.dart 76:7   main.<fn>.<fn>
  test/client_test.dart 74:22  main.<fn>.<fn>
  
00:02 +3 -5: test/client_test.dart: client Set auth [E]                                                                                                                                                          
  Expected: non-empty
    Actual: ''
  
  package:test_api             expect
  test/client_test.dart 82:7   main.<fn>.<fn>
  test/client_test.dart 80:22  main.<fn>.<fn>
  
00:02 +3 -6: test/client_test.dart: client Set session [E]                                                                                                                                                       
  Expected: non-empty
    Actual: ''
  
  package:test_api             expect
  test/client_test.dart 93:7   main.<fn>.<fn>
  test/client_test.dart 91:25  main.<fn>.<fn>
  
00:02 +3 -7: test/client_test.dart: client Update user [E]                                                                                                                                                       
  Expected: null
    Actual: 'Not logged in.'
  
  package:test_api             expect
  test/client_test.dart 113:7  main.<fn>.<fn>
  
00:02 +3 -8: test/client_test.dart: client Get user after updating [E]                                                                                                                                           
  Expected: <Instance of 'String'>
    Actual: <null>
     Which: is not an instance of 'String'
  
  package:test_api              expect
  test/client_test.dart 120:7   main.<fn>.<fn>
  test/client_test.dart 118:37  main.<fn>.<fn>
  
00:02 +8 -8: Some tests failed.                   

.update running into duplicate key violation

Bug report

Describe the bug

Updating existing row results in Duplicate key value violates unique constraint error.

To Reproduce

  1. Create a table
  2. Insert a row
  3. Try to use .update on the row
  4. See error

Expected behavior

.update should update the values in the existing row without throwing an error

Error message

PostgrestError(message: duplicate key value violates unique constraint "chats_pkey", code: 23505, details: Key (id)=(28) already exists., hint: null)

System information

  • supabase: ^0.2.8
  • Flutter: 2.2.3

Getting 404 on update

Bug report

Describe the bug

Getting 404 PostgrestError(message: [], code: null, details: null, hint: null) when printing status and error
A clear and concise description of what the bug is.
The update is not going forward

To Reproduce

running a simple update final response = await client!.from('profiles').update(entry.toMap()).eq('id', UUID).execute();

Steps to reproduce the behavior, please provide code snippets or a repository:

running a simple update final response = await client!.from('profiles').update(entry.toMap()).eq('id', UUID).execute();

Expected behavior

The update resolving without issues

System information

  • OS: Windows
  • Android Mobile App
  • Version of supabase-flutter latest 0.2.8

Android/iOS deeplink not working due to URI fragment

I am super excited to see a dedicated flutter package for Supabase! Kudos for that 👏

Has anyone gotten deeplinks to work on Android and iOS @phamhieu ?
I report this, expecting it not to work. Should it somehow work for you, I will be glad to scrutinize a working example until I get mine to work.

I just can't deeplinks to work on Android (and iOS probably as well). I came across this bug in April, when I tried to enable the deeplink logins with Supabase.

There is a bug inside Flutter, where it ignores the URI fragment, which Supabase uses by design choice, e.g. my-url.com?queryParam=unrelatedToSupabase#accessToken=...

Everything after the URI fragment (#, also called anchor) gets cut from the deeplink URL.

Here is the related issue: flutter/flutter#80666
and PR that hopefully fixes it: flutter/engine#26185

On web everything should be working and I am using it for my project daily 💯

Steps to reproduce:

  1. Configure Deeplinks
  2. Set deeplink (might be required) in Android App Info
  3. Correctly configure redirect URLs
  4. Login with Gitlab or similar
  5. App reopens via deeplink
  6. Doesn't have accessToken

Debug log:

I/flutter ( 5229): onReceivedAuthDeeplink uri: https://studyu-designer.codemagic.app/#/%23access_token=...
I/flutter ( 5229): ***** onErrorAuthenticating: No access_token detected.

Reset code for Email works correctly only for the first time.

Reset code for Email

I have my own website host at supabase settings page, when I reset password supabase send me an email. When I click on the email Reset Passworkd link for the first time for every new email it works fine, but for the second or 3th time when I send reset link to email and click on the link sended to email I get error as

https://myHost.com/#error_code=404&error_description=User+not+found

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a supabase project and disable email conformation
  2. Create a simple app with 2 Button 1) Sign Up and 2) Forget password
  3. on 1st Button Sign up call this: auth.signIn(email: email, password: password)
  4. on the 2nd button Forget the password call this: auth.api.resetPasswordForEmail(email)
  5. For the first time forget the password will work. on the second and 3rd time, it will not work.

JWT Expired

JWT Expired and did not refresh automatically

After a hour or two when I request to select a table data using supabase.from('table), I get the error of JWT expired, and it does not refresh automatically.

The JWT token shall refresh automatically if it's expired.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a project, log in and create a profiles table and get a list of profiles.
  2. Close the app and check app again after couple of hours.
  3. JWT expired error will raise

auth.signUp not returning the data.user

Bug report

Describe the bug

First of all, thanks for this package. It is awesome to be able to use Supabase with Flutter!
According to the documentation, if Email Confirmations is enabled, the signUp() method should return the user filled in, but session should be empty. Nevertheless, the reality is that the response object always comes with all its properties (data, error, provider, rawData and url) as null.

To Reproduce

When Email Confirmationsis turned on, response.data is always null in the code below.

Future<String> _signUp(Registration registration) async {
    final response = await supabase.auth
        .signUp(registration.user.email!, registration.password!);

    if (response.error == null) {
      print('Sign up was successful for user ID: ${response.data!.user!.id}'); // DATA IS ALWAYS NULL
      return response.data!.user!.id;
    }

    print('Sign up error: ${response.error!.message}');
    return '';
  }

Expected behavior

When Email Confirmationsis turned on, response.data is not null and has the user property filled in with the newly created user.

Screenshots

Below is our configuration together with the code and the watch on the breakpoint.

image
image

System information

  • OS: macOS, Windows 10
  • Tested on: Chrome, iOS and Android
  • Version of supabase:
    • supabase: ^0.2.7
    • supabase_flutter: ^0.2.8

Thanks for your support!

Deep Linking is only supported on Android and iOS

Bug report

Describe the bug

I consistently get a weird bug only on macOS (desktop) when adding Supabase.initialize() to the main() function.

On Android and iOS (both emulators and real devices) this bug does not… 😞

To Reproduce

My “one-file” ./lib/main.dart (for short):

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

import 'package:supabase_flutter/supabase_flutter.dart';

Future<void> main() async {
  // Add instance of the WidgetsBinding.
  // See: https://github.com/supabase/supabase-flutter#getting-started
  WidgetsFlutterBinding.ensureInitialized();

  // Add Supabase connector.
  // See: https://github.com/supabase-community/supabase-flutter-quickstart/blob/main/lib/main.dart
  await Supabase.initialize(
    url: '[SUPABASE_ENDPOINT_URL]',
    anonKey: '[SUPABASE_ANON_KEY]',
    authCallbackUrlHostname: 'login-callback',
    debug: true,
  );

  // Run main application widget.
  runApp(const MyApp());
}



/// Main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      debugShowCheckedModeBanner: false,
      themeMode: ThemeMode.system,
      initialRoute: '/',
      routes: <String, WidgetBuilder>{
        '/': (_) => const SplashScreen(),
      },
    );
  }
}


/// Create AuthState.
class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
  @override
  void onUnauthenticated() {}

  @override
  void onAuthenticated(Session session) {}

  @override
  void onPasswordRecovery(Session session) {}

  @override
  void onErrorAuthenticating(String message) {}
}



/// Screen for the Splash page (initial page of the app).
class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

  @override
  _SplashScreenState createState() => _SplashScreenState();
}

/// State for the splash screen.
class _SplashScreenState extends AuthState<SplashScreen> {
  @override
  void initState() {
    // Recovery Supabase session.
    recoverSupabaseSession();
    // Init state.
    super.initState();
  }

  @override
  void dispose() => super.dispose();

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: CircularProgressIndicator(color: Color(0xFF00AB55)),
      ),
    );
  }
}

Expected behavior

It would be great to run a desktop macOS (and probably Windows and GNU/Linux) app with Supabase without errors. Like it does on Android and iOS.

Screenshots

I run project with VS Code standard debugger (F5):

Launching lib/main.dart on macOS in debug mode...

lib/main.dart:1

--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:x86_64, id:3F1370FE-97D5-54BC-9DF8-54CF550D3229 }
{ platform:macOS, name:Any Mac }

Connecting to VM Service at ws://127.0.0.1:58514/LbvTAgExSus=/ws

flutter: ***** Supabase init completed Instance of 'Supabase'
flutter: ***** SupabaseAuthState startAuthObserver
flutter: ***** SupabaseDeepLinkingMixin startAuthObserver

════════ Exception caught by services library ══════════════════════════════════
The following MissingPluginException was thrown while activating platform stream on channel uni_links/events:
MissingPluginException(No implementation found for method listen on channel uni_links/events)

When the exception was thrown, this was the stack
#0      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:154
<asynchronous suspension>
#1      EventChannel.receiveBroadcastStream.<anonymous closure>
package:flutter/…/services/platform_channel.dart:486
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════

...

The debugger shows line 154 in the /usr/local/Caskroom/flutter/2.5.3/flutter/packages/flutter/lib/src/services/platform_channel.dart file:

Screenshot 2021-11-20 at 11 02 38

OK. I click “Continue” button (F5) and debugger shows line 15 in /usr/local/Caskroom/flutter/2.5.3/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.5.1/lib/uni_links.dart file:

Screenshot 2021-11-20 at 11 04 39

Next, click F5 once again and see line 52 in /usr/local/Caskroom/flutter/2.5.3/flutter/.pub-cache/hosted/pub.dartlang.org/supabase_flutter-0.2.9/lib/src/supabase_deep_linking_mixin.dart file:

Screenshot 2021-11-20 at 11 06 59

If I click F5 again, debugger run app with this message:

...

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method getInitialLink on channel uni_links/messages)
#0      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:154
<asynchronous suspension>
#1      getInitialUri
package:uni_links/uni_links.dart:15
<asynchronous suspension>
#2      SupabaseDeepLinkingMixin._handleInitialUri
package:supabase_flutter/src/supabase_deep_linking_mixin.dart:52
<asynchronous suspension>

🤞 Yes, the application runs and works fine… but it is very inconvenient when debugging and developing! I constantly have to press F5 many times every time I change the code.

System information

$ flutter doctor -v

[✓] Flutter (Channel stable, 2.5.3, on macOS 11.6.1 20G224 darwin-x64, locale en-GB)
    • Flutter version 2.5.3 at /usr/local/Caskroom/flutter/2.5.3/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 18116933e7 (5 weeks ago), 2021-10-15 10:46:35 -0700
    • Engine revision d3ea636dc5
    • Dart version 2.14.4

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/koddr/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.1, Build version 13A1030d
    • CocoaPods version 1.11.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2020.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)

[✓] VS Code (version 1.62.3)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.28.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 11.6.1 20G224 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 95.0.4638.69

• No issues found!

Additional context

Commands flutter clean and flutter pub get did not resolve the problem.

macOS support

Feature request

Thanks for this great package!

I would like to use the supabase-flutter package with my app that runs on both the web and macOS.

Is your feature request related to a problem? Please describe.

I am using Google OAuth and it works well on the web. When running the macOS app, I can open the Google SignIn page. The callback scheme does not open my app, however. Instead, the Google Request keeps loading and the browser window loses focus.

Is a totally different implementation for macOS required? It seems to me that as long as the callback scheme is correct, I should be able to retrieve the resulting callback and handle the authentication logic from there as usual.

Realtime RLS Broadcasts Errors

Realtime RLS will be broadcasting database changes with errors so that clients can capture what went wrong when listening to database changes.

Please see here for the current error states: https://github.com/supabase/walrus/tree/generic_claims#error-states.

Realtime RLS will broadcast errors as either null (no errors) or an array of strings (at least one error present).

Here are two example Realtime RLS JSON payloads with errors:

{
      "columns": [{"name": "id", "type": "int8"}, {"name": "details", "type": "text"}],
      "commit_timestamp": "2021-12-28T23:59:38.984538+00:00",
      "schema": "public",
      "table": "todos",
      "type": "UPDATE",
      "old_record": {"details": "previous test", "id": 12, "user_id": 1},
      "record": {"details": "test...", "id": 12, "user_id": 1},
      "errors": ["Error 413: Payload Too Large"]
}
{
      "columns": [],
      "commit_timestamp": null,
      "schema": "public",
      "table": "todos",
      "type": "UPDATE",
      "old_record": {},
      "record": {},
      "errors": ["Error.."]
}

Notice:

  • columns will always be an array but can be empty
  • commit_timestamp will either be a string or null
  • old_record/record will always be an object but can be empty

Select entries from a date range

Bug report

Describe the bug

I am trying to make a request and only get the data between two dates. I thought this would work but maybe I am completely wack haha.

Right now it doesn't apply both the gte and lte but rather it takes the last applied one. How would I go about this?

startdate = 2021-11-1
enddate = 2021-11-30

final response = await supabase
        .from('expenses')
        .select(
            'id, amount, transaction_date, categories (id, name), profiles (id, name)')
        .eq('household_id', householdId)
        .gte('transaction_date', startDate.toIso8601String())
        .lte('transaction_date', endDate.toIso8601String())
        .execute();

To Reproduce

startdate = 2021-11-01
enddate = 2021-11-30

final response = await supabase
        .from('someTable')
        .select('id, date')
        .gte('date', startDate.toIso8601String())
        .lte('date', endDate.toIso8601String())
        .execute();

Expected behavior

I expect to only see items within that year and month.

System information

  • OS: Windows
  • Browser (if applies) [e.g. chrome, safari]

Additional context

image

Flutter Web Popup login

Hi there,
Do you know, how we can do flutter web pop up login and return back to same screen?

Inability to use operators other than `eq` in the realtime filter within the `.from` argument

When I use any operator other than eq in the .from argument, I get the following error:

relation "<schema>.<table>:<column>=<operator>.<value>" does not exist`

For the following operators: neq, lt, lte, gt, and gte.

For instance:

  • This works:

    supabaseClient.from("messages:is_seen=eq.false") 
  • This does not work:

    supabaseClient.from("messages:is_seen=neq.false") 

    It gives the following error:

    relation "public.messages:is_seen=neq.false" does not exist
    

Versions

  • supabase: ^0.2.13
  • flutter: 2.8.1

Flutter documentation for setting up different auth solutions

Improve documentation

Link

https://supabase.com/docs/guides/with-flutter

Describe the problem

In the documentation, it's explained to use AuthState which becomes quite tedious and not very straightforward. Comparing this to Firebase equivalent https://firebase.flutter.dev/docs/auth/usage which is super straightforward and can be implemented with any kind of architecture.

For example, if you are using Riverpod you don't have StatefulWidget or StatelessWidget making the current documentation a pain to follow.

Describe the improvement

A section for only the code-related parts similar to how Firebase does it. I would like to go to "Flutter" -> "Auth" and then see the documentation for how to set up auth.

Additional context

I will link the FlutterFire documentation because that is super easy to follow even if you are using different architectures etc
https://firebase.flutter.dev/docs/auth/usage

Use hive instead of shared_preferences

Feature request

Is your feature request related to a problem? Please describe.

Currently, the way to store the user session is made by the plugin shared_preferences. It is not a secure storage, making the user info vunerable.

Describe the solution you'd like

Make use of a more secure storage solution, such as hive, since it's lightweight, fast and has encryption built-in. This is the storage solution used by firedart, the pure-dart firebase implementation.

Describe alternatives you've considered

Some other storage solutions, but they have some downsides:

With all the downsides presented above, hive is the best storage solution to store the user session: it's fast, lightweight and has built-in encryption.

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.