I'm trying to create a login page for an app that's linked to a supabase database but I'm getting an error for the user authentication method.
Error
The method 'execute' isn't defined for the type 'PostgrestFilterBuilder', dart(undefined_method) [Ln 31, Col 10] Try correcting the name to the name of an existing method, or defining a method named 'execute'.
Login Page:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
class CustomLoginPage extends StatefulWidget {
const CustomLoginPage({Key? key}) : super(key: key);
@override
_CustomLoginPageState createState() => _CustomLoginPageState();
}
class _CustomLoginPageState extends State<CustomLoginPage> {
late final TextEditingController _firstNameController = TextEditingController();
late final TextEditingController _lastNameController = TextEditingController();
late final TextEditingController _idNumberController = TextEditingController();
bool _isLoading = false;
Future<void> _signIn() async {
setState(() {
_isLoading = true;
});
final client = Supabase.instance.client;
final response = await client
.from('user_profile')
.select()
.eq('first_name', _firstNameController.text.trim())
.eq('last_name', _lastNameController.text.trim())
.eq('id_number', _idNumberController.text.trim())
.execute();
if (response.error != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Login failed: ${response.error?.message}'),
backgroundColor: Theme.of(context).colorScheme.error,
),
);
} else {
final data = response.data;
if (data != null && data.isNotEmpty) {
// Handle successful authentication.
Navigator.of(context).pushReplacementNamed('/account');
} else {
// Handle user not found.
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('User not found. Please check your credentials.'),
backgroundColor: Colors.red,
),
);
}
}
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
@override
void dispose() {
_firstNameController.dispose();
_lastNameController.dispose();
_idNumberController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Custom Sign In')),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
TextFormField(
controller: _firstNameController,
decoration: const InputDecoration(labelText: 'First Name'),
),
TextFormField(
controller: _lastNameController,
decoration: const InputDecoration(labelText: 'Last Name'),
),
TextFormField(
controller: _idNumberController,
decoration: const InputDecoration(labelText: 'ID Number'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _isLoading ? null : _signIn,
child: Text(_isLoading ? 'Loading...' : 'Sign In'),
),
],
),
);
}
}
Main file:
import 'package:flutter/material.dart';
import 'pages/login.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
//void main() => runApp(MyApp());
void main() async {
await Supabase.initialize(
url: 'https://mtngkmicxfgticmpfrxi.supabase.co',
anonKey:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im10bmdrbWljeGZndGljbXBmcnhpIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDc0MTAwMTgsImV4cCI6MjAyMjk4NjAxOH0.GaBRK6gZqJoFeG43RmVJSH34AQNzb76x2WcOilO4SS0',
);
runApp(MyApp());
}
final supabase = Supabase.instance.client;
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
theme: ThemeData(
// Specify a brightness that matches the color scheme
brightness: Brightness.dark,
primaryColor: Colors.blue,
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue,
brightness:
Brightness.dark, // Make sure this matches the above brightness
).copyWith(
secondary: Colors.blue,
),
// Define the default font family.
fontFamily: 'Montserrat',
// Define the default TextTheme.
textTheme: TextTheme(
headline6: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
),
),
home: LoginPage(),
);
}
}
The method I had originally tried was this, but I just got another error related to the from command for this:
final response = await supabase
.from('your_table')
.select()
.eq('column_name', 'value')
.execute();
From what I can see, the execute()
method doesn't exist on the PostgrestFilterBuilder
class.
And by checking the Supabase documentation and the package code the PostgrestFilterBuilder
is already a Future
which you can simply await
to finish your query. So, the correction would be to simply remove the .execute()
call as follows:
final response = await client
.from('user_profile')
.select()
.eq('first_name', _firstNameController.text.trim())
.eq('last_name', _lastNameController.text.trim())
.eq('id_number', _idNumberController.text.trim())
Hope this helps!
Edit:
Also, based on the documentation, in your case, the response
will be an object of type List<Map<String, dynamic>>
and it won't have .error
or .data
properties. The response
is the result of the query.
In that case, you might want to rewrite your code as this:
Future<void> _signIn() async {
setState(() {
_isLoading = true;
});
final client = Supabase.instance.client;
try {
final response = await client
.from('user_profile')
.select()
.eq('first_name', _firstNameController.text.trim())
.eq('last_name', _lastNameController.text.trim())
.eq('id_number', _idNumberController.text.trim());
if (response.isNotEmpty) {
// Handle successful authentication.
if (context.mounted) {
Navigator.of(context).pushReplacementNamed('/account');
}
} else {
// Handle user not found.
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('User not found. Please check your credentials.'),
backgroundColor: Colors.red,
),
);
}
}
} catch (err) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Login failed: ${err.toString()}'),
backgroundColor: Theme.of(context).colorScheme.error,
),
);
}
}
if (context.mounted) {
setState(() {
_isLoading = false;
});
}
}