How to get value from supabase without .execute()? - flutter - flutter

So, Supabase announced that they're updated supabase-flutter package into v.1.0 and I want to give it a try.
This is how they're fetching data from database in previous version:
final res = await supabase.from('my_table').select().execute(); // <= They're using execute
final error = res.error;
if(error != null) {
// handle error
}
final data = res.data;
But in this new version, they're deprecating .execute().
As the blog said,
No more .execute() to get the data
We want this SDK to be as close as possible to the JavaScript SDK to provide consistent developer experience no matter what programming language you are using. Prior to the 1.0 update, whenever you called the postgrest endpoints, you had to call .execute() at the end of each query.
.execute() is now deprecated. You no longer needed it to query data from your Supabase database.
This is the new syntax:
try {
final data = supabase.from('my_table').select();
// 'data' data type is PostgrestFilterBuilder
} catch (error) {
// handle error
}
How can I get value from variable 'data'? Also I want to get a single value from the data.
Any help would be appreciated

I think the issue is that you are missing a await before the supabase.from in your code.

Related

How to fetch data from supabase

I tried this by exploring web and supabase docs but nothing really happens
import 'package:supabase/supabase.dart';
class supahandelar {
static const SupaUrl = 'UrlFromSupabase';
static const SupaKey = 'KeyFromSupabase';
final client = SupabaseClient(SupaUrl, SupaKey);
getData() async {
var response = await client.from('Pokemons').select().execute();
print("Respnse");
print(response);
}
}
It gives me this output on console:
instance of 'minified:hy<erased>'
Also not getting any output in widgets/ui
Can anyone please suggest me simple methods to only fetch data.
It was just an RSL issues. When i tried with new databases without RSL disabled it worked.
So i need to create RSL Policy of who to allow read data...
For Ex:-I Added true for all user to read
If anyone face this issue please check/ Create RSL Policy.

Flutter / RiverPod - how to load StateProvider initial state from Firestore

I'm stuck with a situation where I am trying to use a RiverPod provider in my Flutter app to represent user preference data. In this case, the user preference data is stored in FireStore.
I'm stuck with understanding how to load provider state from Firestore. Currently, I'm trying to use the "userPreferencesFutureProvider" to load the 'GdUserPreferences" data from a service that calls Firestore, which then pushes the data into "userPreferencesProvider" using the 'overrideWith' method. However, when I access the user preference data via the 'userPreferencesProvider' provider the data loaded from Firestore is not present
final userPreferencesFutureProvider = FutureProvider<bool>( (ref) async {
final p = ref.watch(userPrefsServiceProvider);
GdUserPreferences? aPrefs = await p.load();
if (aPrefs == null) {
aPrefs = GdUserPreferencesUtil.createDefault();
}
userPreferencesProvider.overrideWith((ref) => UserPreferencesNotifier(p,aPrefs!));
return true;
});
final userPreferencesProvider = StateNotifierProvider<UserPreferencesNotifier,GdUserPreferences>((ref) {
return UserPreferencesNotifier(ref.watch(userPrefsServiceProvider),GdUserPreferences());
});
Any suggestions?
Update
Further to the feedback received I have updated my code as shown below, but this still doesn't work...
final userPreferencesFutureProvider = FutureProvider<bool>( (ref) async {
// get service that wraps calls to Firestore
final p = ref.watch(userPrefsServiceProvider);
// load data from Firestore
GdUserPreferences? aPrefs = await p.load();
// if none found then create default values
if (aPrefs == null) {
aPrefs = GdUserPreferencesUtil.createDefault();
}
// push state into a provider that will be used
ref.read(userPreferencesProvider.notifier).update(aPrefs);
// this future returns a boolean as a way of indicating that the data load succeeded.
// elsewhere in the app access to the user preference data is via the userPreferencesProvider
return true;
});
final userPreferencesProvider = StateNotifierProvider<UserPreferencesNotifier,GdUserPreferences>((ref) {
print('default provider');
return UserPreferencesNotifier(ref.watch(userPrefsServiceProvider),GdUserPreferences());
});
class UserPreferencesNotifier extends StateNotifier<GdUserPreferences> {
// service is a wrapper around FireStore collection call
final GdUserPreferencesService service;
UserPreferencesNotifier(this.service, super.state);
void update(GdUserPreferences aNewPrefs) {
print('update state');
state = aNewPrefs;
}
}
The purpose of having a separate FutureProvider and StateNotifierProvider, is that I can insert the FutureProvider when the app first loads. Then when I want to access the user preference data I can use the straight forward StateNotifierProvider, which avoids the complications of having Future Providers all over the app.
Note: using the print methods I can show that the 'update' method is called after the userPreferencesProvider is first created, so I can't understand why the data is not updated correctly
Apologies to all responders...
The problem was caused by a coding error on my side. I had two versions of 'userPreferencesProvider' defined in two different locations. Taking out the rogue duplicate definition and it now works fine.

Flutter/Dart: return not waiting "toList" with async function to finish

I'm working on an API sync using Flutter and SQFLite.
I get the data from the API, map it, and then add to SQL item by item:
return (response as List).map((tmp) {
print('• API: apiSync - Inserting News');
DBProvider.db.updateNews(ArtNews.fromJson(tmp));
}).toList();
Everything works fine, but there is a small problem: the return is called before the 'updateNews' is done.
updateNews is a simple async function that writes data on SQFLite.
This creates a big issue: the app opens before the sync is over and data is still being written on DB.
I've tried using AWAIT, but it doesn't make any effect:
(response as List).map((tmp) async{
print('• API: apiSync - Inserting $type');
await DBProvider.db.updateNews(ArtNews.fromJson(tmp));
}).toList();
return 'done';
updateNews is called dozens of times, the toList ends, returns 'done', but the updateNews is still adding content to the DB.
I guess there is something I'm missing on toList or async. Any ideas? Thanks!
Try this:
await Future.wait((response as List).map((tmp) {
print('• API: apiSync - Inserting $type');
return DBProvider.db.updateNews(ArtNews.fromJson(tmp));
}));
return 'done';
Gist for reference:
https://dartpad.dev/?id=e72b1dc9013e2add447a90979bed7aab

appwrite list users search params

I am trying to use appwrite server sdk list users to get userid from an email.
The documentation says there is a search: option that can be used but no where does it say what the format of that String? is.
What is the format of the search: String? to only get a list of users whose email matches?
void main() { // Init SDK
Client client = Client();
Users users = Users(client);
client
.setEndpoint(endPoint) // Your API Endpoint
.setProject(projectID) // Your project ID
.setKey(apiKey) // Your secret API key
;
Future result = users.list(search: '<<<WHAT GOES HERE>>>');
}
:wave: Hello!
Thanks for bringing this question up, this is definitely not well documented, I'll note this down and try to make it clearer in the docs, but here's how you'd approach this in Dart:
final res = users.list(search: Query.equal('email',
'email#example.com'));
res.then((response) {
print(response.users[0].toMap());
}).catchError((error) {
print(error);
});
The Query object generates a query string, and works similar to how listDocument would work. The difference here is that it only takes a single query string instead of a list.

FireStore read fails silently and I have no idea why

Help is much appreciated how to trace down this issue, because I am running out of ideas.
I am calling the function getOrderCollection, below, but it aborts after the first line var myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get(); Without trowing anything to the console or jumping into some library when debugging. When I click next statement it jumps back to the calling function.
I am authenticated to the database, companyCollection = FirebaseFirestore.instance.collection('companies') provides an initialized object pointing to the collection and myCompany is a constant with the document id entered by copy/paste.
If some rules for the database but I can't see successful or denied queries with the monitor.
Any ideas how I can proceed tracing down the issue?
Future<void> getOrderCollection() async {
var myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get();
print("companyDoc fetched");
final myDeliveryDocRef = myCompanyDoc.data()['delivery'].toString();
orderCollection = FirebaseFirestore.instance.collection('companies').doc(myCompany).collection('features').doc(myDeliveryDocRef).collection('orders');
orderBriefDoc = FirebaseFirestore.instance.collection('companies').doc(myCompany).collection('features').doc(myDeliveryDocRef);
}
UPDATE: This is collection > document what corresponds to final String myCompany = '4U4kZKXkr3rHA6B04S5K';
As we discussed in your comments, the issue was that you forgot to await the getOrderCollection() function. Even though, as you mentioned, your caller function _deliveryRepository.initRepository() was awaited, you still had to await getOrderCollection() inside your caller method to make sure that the code is waiting for the getOrderCollection() to be executed before it proceeds to the next line.
In general, you want to have some error handling and to type the known types/classes (avoid using var).
Error handling - for async/await place the code inside a try/catch.
Typing - Dart is type safe, which is really great to prevent runtime errors.
Depending on your setup, you might be able to hover over the Firestore.instance.collection(...).doc(...) to see the return type. .doc(...).get() returns a DocumentSnapshot and .collection(...).get() returns a CollectionSnapshot.
Using the above, it should be easier to debug:
Future<void> getOrderCollection() async {
try {
DocumentSnapshot myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get();
print("companyDoc fetched");
final myDeliveryDocRef = myCompanyDoc.data()['delivery'].toString();
} catch(e) {
print('Error: ' + e.toString());
}
}
Don't forget to await your other 2 Firestore queries.