Fetching data from Supabase in flutter - flutter

Anyone can help me with this, I'm trying to fetch data from a table in Supabase but it's showing error on the app screen.
I want to build an app that reads the data from Supabase without any authentication, only reading and displaying the data from the table, here I'm just testing before I start building my app.
a screenshot from the main page in the app
My code in main.dart
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: '[https://bougcsiwnimbmnmvwjlb.supabase.co]',
anonKey: '[eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0Mzc5NzQyOCwiZXhwIjoxOTU5MzczNDI4fQ.Ac5s-ZOyUV-2rRoP_GUuPvdt7tGNocCSq-LU-ZtBVqQ]',
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
// SuPabase
class _MyHomePageState extends State<MyHomePage> {
Future<void> _getProfile(String name) async {
late final _usernameController ;
#override
Future<Widget> build(BuildContext context) async {
final response = await Supabase.instance.client
.from('channels')
.select()
.single()
.execute();
if (response.error != null && response.status != null) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(response.error!.message)));
}
if (response.data != null) {
_usernameController = response.data!['name'] as String;
}
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
children: [
Text(_usernameController,
),
],
),
);
}
}
#override
Widget build(BuildContext context) {
throw UnimplementedError();
}
}
I really appetite if anyone can help in this.

I think I can spot few spots that you might want to fix.
First, you want to remove the [] around your Supabase URL and Supabase anon key like this.
await Supabase.initialize(
url: 'https://bougcsiwnimbmnmvwjlb.supabase.co',
anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTY0Mzc5NzQyOCwiZXhwIjoxOTU5MzczNDI4fQ.Ac5s-ZOyUV-2rRoP_GUuPvdt7tGNocCSq-LU-ZtBVqQ',
);
Also, it seemed like you had some mismatch of brackets in your widget definition. I think this is along the line of what you wanted to do:
class _MyHomePageState extends State<MyHomePage> {
String? name;
Future<void> _getProfile() async {
final response = await Supabase.instance.client
.from('channels')
.select()
.single()
.execute();
if (response.error != null && response.status != null) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(response.error!.message)));
}
if (response.data != null) {
setState(() {
name = response.data!['name'] as String;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
children: [
name == null ? const Text('loading') : Text(name!),
],
),
);
}
#override
void initState() {
_getProfile();
super.initState();
}
}

Related

Flutter rest GETX map inside Obx not refreshing data on gui side

Hello I have simple script I download data from from Rest api , there is my controller
and when I submit the button I Clear the list inside object Employee, after click I call the deleteEmployee() (int the future CRUD operations per row inside table,) , data are cleared, but data inside widget they are not refreshed. and I would like somethin more with that I need to show in table and make same operation per row.
I cant figure where is a problem.
after click the button must look like
class EmployeeController extends GetxController {
var empData = <Employe>[].obs;
#override
void onInit() {
fetchEmployee();
super.onInit();
}
void fetchEmployee() async {
final response =
await http.get(
Uri.parse('http://dummy.restapiexample.com/api/v1/employees'));
if (response.statusCode == 200) {
final string = response.body;
final parsed = json.decode(string);
Employe emp = Employe.fromJson(parsed);
Employe empx = Employe( message: "sampleTest", status: '123', data: emp.data.getRange(0, 4).toList() );
List<Employe> e = [];
e.add(empx);
e.add(emp);
empData.value = e;
} else {
throw Exception('Failed to load emplo');
}
}
void deleteEmployee (String enumId){
debugPrint(empData.toString());
debugPrint("before");
int index = empData.indexWhere((ele) => ele.message == enumId);
empData[index].data.clear();
debugPrint("after");
debugPrint(empData.toString());
}
}
void main() {
runApp(const MyApp());
}
final EmployeeController employeeController = Get.put(EmployeeController());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Obx(() => Row(
children: employeeController.empData
.map(
(e) => Expanded(
child: Column(
children: [
Text(e.message),
Text(e.toString()),
IconButton(
onPressed: () {
employeeController.deleteEmployee(e.message);
},
icon: Icon(Icons.abc_rounded),
)
],
),
),
)
.toList())),
);
}
}
In _MyHomePageState try to use employeeController.empData.value instead of employeeController.empData.
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Obx(() => Row(
children: employeeController.empData.value
.map(
(e) => Expanded(
child: Column(
children: [
Text(e.message),
Text(e.toString()),
IconButton(
onPressed: () {
employeeController.deleteEmployee(e.message);
},
icon: Icon(Icons.abc_rounded),
)
],
),
),
)
.toList())),
);
}
}

How to fix hive box already open error in flutter?

I am trying to use hive to store data on a local machine using hive but each time when I compile the code it gives the error "The box "notebook" is already open and of type Box."
Can someone help me to resolve the issue as I am new to it? Thanks
I am just trying to add data to the database in this app without any change to the state of the app interface. I have tried to change the main method to void but no luck on this.
All the code is located in the main file
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'notes.dart';
import 'notesStoring.dart';
Future main() async{
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
Hive.registerAdapter(NotesAdapter());
await Hive.openBox<NotesAdapter>('noteBook');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
#override
void dispose() {
Hive.close();
// TODO: implement dispose
super.dispose();
}
#override
Future incrementCounter(String title) async {
final notes = Notes()
..title = title;
final box =Boxes.getNotesValues();
box.add(notes);
}
final titleForNotes=TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
TextField(
controller: titleForNotes,
cursorColor: Colors.pink,
),
ValueListenableBuilder<Box<Notes>>(valueListenable: Boxes.getNotesValues().listenable(), builder: (context,box,_){
final noteBook =box.values.toList().cast<Notes>();
return buildContent(noteBook);
})
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
incrementCounter(titleForNotes.text);
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class Boxes {
static Box<Notes> getNotesValues()=>Hive.box<Notes>('noteBook');
}
Widget buildContent(List<Notes> noteBook){
return Column(
children: [
Expanded(child:
ListView.builder(
padding: EdgeInsets.all(8),
itemCount: noteBook.length,
itemBuilder: (BuildContext context, int index){
final notes= noteBook[index];
return buildTransaction(context, notes);
}
)
)
],
);
}
Widget buildTransaction(
BuildContext context,
Notes notes,
){
return Card(
color: Colors.green,
child: Text(notes.title),
);
}
1.You can open your notebook Box in the main method of your app:
Future<void> main() async {
...
final appDocumentDirectory = await
path_provider.getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
Hive.registerAdapter(UserAdapter());
// open the user box
await Hive.openBox('notebook');
_setUpLogging();
runApp(MultiProvider(providers: providers, child:
StartupApplication()));
}
2 Access the previously opened box like below:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// user box
Box notebookBox;
#override
void initState() {
super.initState();
// get the previously opened user box
notebookBox = Hive.box('notebook');
}
#override
Widget build(BuildContext context) {
// check for your conditions
return (notebookBox.values.isNotEmpty && notebookBox.get(0).active == 1)
? HomeView()
: Intro();
}
}

How to pass a drawer with a string inside to next screen

I have the next block of code where I'm getting the AppVersion using a library and after that I'm passing the AppVersion to a drawer. That drawer I send it to next screen but when I open the drawer on the next screen is showing the AppVersion as NULL. What can be the issue ?
I will provide below the full code source and maybe somebody can help me to figure out where is the bug.
import 'package:flutter/material.dart';
import 'package:package_info/package_info.dart';
void main() {
runApp(FirstPage());
}
class FirstPage extends StatefulWidget {
final String title;
FirstPage({Key key, this.title}) : super(key: key);
#override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
String packageAppVersion = '';
#override
void initState() {
super.initState();
versionCheck();
}
Future<void> versionCheck() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
setState(() {
packageAppVersion = packageInfo.version;
});
}
Widget buildDrawerForSecondPage(BuildContext context) {
return new Drawer(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: new Column(
children: [
Flexible(
child: new ListView(
children: <Widget>[],
),
),
Flexible(
flex: 0,
child: Text("App version: $packageAppVersion"),
)
],
),
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Drawer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SecondPage(
title: 'Second Page',
drawer: buildDrawerForSecondPage(context),
),
);
}
}
class SecondPage extends StatefulWidget {
final String title;
final Drawer drawer;
SecondPage({Key key, this.title, this.drawer}) : super(key: key);
#override
_SecondPageState createState() => _SecondPageState(drawer);
}
class _SecondPageState extends State<SecondPage> {
String packageAppVersion = '';
final Drawer drawer;
_SecondPageState(this.drawer);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
endDrawer: drawer,
body: Container(),
);
}
}
Thanks in advance.
That's because you are using a .then() syntax, the AppVersion actually gets updated but a bit later hence the null value. You could await the version before the run() method and then pass it down to MaterialApp, or you could try using a setState after the print inside then(). Let me know if this fixes your issue.
Initially, the value of packageAppVersion is null, that is what it is being shown in the UI. So to update the UI you need to use setState. Check the below code for a better understanding:
#override
void initState() {
super.initState();
versionCheck();
}
Future<void> versionCheck() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
setState((){
packageAppVersion = packageInfo.version;
});
print('App version received: $packageAppVersion');
}
I found the fix for above code, but I don't understand why is working only like this (removed the drawer property and the constructor from the _SecondPageState) :
class SecondPage extends StatefulWidget {
final String title;
final Drawer drawer;
SecondPage({Key key, this.title, this.drawer}) : super(key: key);
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
String packageAppVersion = '';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
endDrawer: widget.drawer,
body: Container(),
);
}
}

Flutter use one Variable in different classes Error: Getter not found: 'allJobs'

I have a Variable in one Class but and i want to use it in all.
In this Example is the allJobs Variable which is declared in Muesnterboerse ore MuensterboerseAAAngebote and i want to use it in senddate().
class Muensterboerse extends StatelessWidget {
var allJobs = 1;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
class MuensterboerseAAAngebote extends StatelessWidget {
var allJobs = 0;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
Future<dynamic> senddata() async {
final response = await http.post(
"https://www.bumsbirnbe.php", body: {
"status": allJobs,
});
var datauser = json.decode(response.body);
String jsonsDataString = datauser.toString();
dynamic jsonData = jsonDecode(jsonsDataString);
print(jsonData);
return jsonData;
}
Update
Now i added your changes to my code but i get the
Error: Unhandled Exception: NoSuchMethodError: The getter 'allJobs' was called on null.
This is my whole code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
GlobalKey _key1 = GlobalKey();
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
int allJobs = 1;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
class AAAngebote extends StatelessWidget {
AAAngebote({Key key}) : super(key: key);
int allJobs = 2;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
final response = await http.post(
"https://www.Bumsbirne.php", body: {
"status": allJobs,
});
var datauser = json.decode(response.body);
String jsonsDataString = datauser.toString();
dynamic jsonData = jsonDecode(jsonsDataString);
print(jsonData);
return jsonData;
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
dynamic jsonData;
callSendData() async {
jsonData = await senddata();
setState(() {});
}
//lol
#override
void initState() {
callSendData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: jsonData == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: jsonData == null ? 0 : jsonData.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('https://kinsta.com/de/wpcontent/uploads/sites/5/2019/09/wordpress-loggst-url-1024x512.jpg'),
radius: 27,
),
title: Text(
jsonData[index]["titel"],
),
subtitle: Text(jsonData[index]["nam_ersteller"]),
trailing: Text(
'25 Km',
style: TextStyle(color: Colors.grey,
fontSize: 12,
decoration: TextDecoration.none,
fontFamily: 'Roboto',),
),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => DetailPage()));
},
);
// return _buildRow(data[index]);
}));
}
}
class DetailPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Der Job'),
),
);
}
}
You can copy paste run full code below
Step 1: You can use GlobalKey and pass to Muensterboerse(key: _key1)
Step 2: In senddata(), do (_key1.currentWidget as Muensterboerse).allJobs;
code snippet
GlobalKey _key1 = GlobalKey();
...
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
...
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
...
Muensterboerse(key: _key1),
output of senddata()
I/flutter (22480): 1
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
GlobalKey _key1 = GlobalKey();
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
int allJobs = 1;
#override
Widget build(BuildContext context) {
return Column(
children: [
Text("$allJobs"),
],
);
}
}
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
/*final response = await http.post(
"https://www.quyre.de/2/Muensterboerse.N.php", body: {
"status": allJobs
});*/
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async{
await senddata();
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Muensterboerse(key: _key1),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

How can my Flutter FutureBuilder change text at multiple places in my layout?

I read carefully the Flutter tutorial; Fetching data from internet: https://flutter.io/cookbook/networking/fetch-data/
My concern is that I want to update multiple texts in my layout.
The implementation only shows a way to update one:
FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
);
This works fine and displays one view at a time.
In Android Studio/Java, I would have done something like:
myTextView1.setText(snapshot.data.data1)
myTextView2.setText(snapshot.data.data2)
myTextView3.setText(snapshot.data.data3)
.....
myTextView10.setText(snapshot.data.data3)
But here in Flutter, I am currently limited to one "Widget" at a time.
Of course, I could provide my whole layout in the return argument, but that would be crazy!
Any idea/suggestion?
An alternative strategy is to have a local variable in the state class and update it when the future arrives. Thus, you can reference that variable wherever you need.
Here is an example:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Post _post = Post("Title 0", "Subtitle0 ", "description 0");
#override
void initState() {
super.initState();
_getPost();
}
void _getPost() async {
_post = await fetchPost();
setState(() {});
}
Future<Post> fetchPost() {
return Future.delayed(Duration(seconds: 4), () {
return Post("Title new", "Subtitle new", "description new");
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
new Text(_post.title),
new Text(_post.subtitle),
new Text(_post.description),
],
),
),
);
}
}
class Post {
final String title;
final String subtitle;
final String description;
Post(this.title, this.subtitle, this.description);
}
You can convert your request to Stream
import 'package:flutter/material.dart';
import 'package:random_pk/random_pk.dart';
import 'dart:async';
class TestWidget extends StatefulWidget {
#override
State<StatefulWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(child: RandomContainer(
width: 200.0,
height: 200.0,
child: Center(child: _MyTextWidget(fetchPost().asStream())),
),),
);
}
Future<String> fetchPost() {
return Future.delayed(Duration(seconds: 4), () {
return "Title data";
});
}
}
class _MyTextWidget extends StatefulWidget {
_MyTextWidget(this.stream);
final Stream<String> stream;
#override
State<StatefulWidget> createState() => _MyTextWidgetState();
}
class _MyTextWidgetState extends State<_MyTextWidget> {
String text;
#override
void initState() {
widget.stream.listen((String data) {
setState(() {
text = data;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Text(text == null ? 'loading' : text);
}
}
In this example RandomContainer changes its color on every setState and it works as indicator, than changes are only in _MyTextWidget