flutterdartflutter-dependenciessupabasesupabase-database

How to fix error: "The method 'execute' isn't defined for the type 'PostgrestFilterBuilder'


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();

Solution

  • 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;
        });
      }
    }