Exception has occurred. PlatformException (PlatformException(-3, Permission denied, )) - database

I tried to build an application, which should write data in a real time database. I tried an example I found in the internet, but now I get an error. The error I get is:
Exception has occurred.
PlatformException (PlatformException(-3, Permission denied, ))
This is the code I tried:
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
//final DBRef = FirebaseDatabase.instance.reference();
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
home: Scaffold(
appBar: AppBar(
title: Text("Testo"),
),
body: Column(
children: <Widget>[
RaisedButton(
child: Text("Write Data"),
onPressed: () {
writeData();
},
),
],
),
),
);
}
void writeData() {
print("pressed");
FirebaseDatabase.instance
.reference()
.child("1")
.set({"id": "ID1", "data": "This is a test"});
}
}
I found in the internet, that my rule in the database could be wrong, that could be the mistake, but I didn't find a solution. This are my rules(I haven´t changed them):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.time < timestamp.date(2020, 7, 29);
}
}
}
I don´t know why I get this error, hopefully someone can help me.

Related

function not fetching data from firebase also showing no error

I have a function to fetch data from firebase firestore everything working fine except its not fetching data and it also shows no error I don't know why please help me out here
my code functions like I would pick a document name using a list picker and tap the get button(inside map page) and it should fetch the data from the database and give results for the specific page
inside the function(fetchmap)the loading bar is also not working I don't know why?
here is my code:
Mappage.dart :
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:helping_hand/UI/Other/Emergency.dart';
import 'package:list_picker/list_picker.dart';
import '../../StateManagement/MapController.dart';
import '../../drawers/bottomnavbar.dart';
import '../Bottom Navigation/My status.dart';
class Mappage extends StatelessWidget {
Mappage({Key? key}) : super(key: key);
final TextEditingController selectPage = TextEditingController();
final List<String> pageList = ['helps','sitrep','location','emergencies', 'users',];
#override
Widget build(BuildContext context) {
MapController mapcontroller = Get.find();
return Scaffold(
body: Stack(
children: [
SizedBox(height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: SizedBox(height: MediaQuery.of(context).size.height,width: MediaQuery.of(context).size.width,
child: Column(
children: [
Stack(
children: [
SizedBox(
height: MediaQuery.of(context).size.height,
child: GetBuilder<MapController>(builder: (_)=>GoogleMap(initialCameraPosition:MapController.initial,
mapType: MapType.normal,markers:mapcontroller.markers,
onMapCreated: (GoogleMapController controller){
mapcontroller.completercontrol.complete(controller);
mapcontroller.googleMapController = controller;
},),)
),
Positioned(
top: 50,
height: 60,
width: MediaQuery.of(context).size.width,
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(width: MediaQuery.of(context).size.width/2,
child: ListPickerField(label:'select', items:pageList,controller:selectPage,)),
ElevatedButton(
style:const ButtonStyle(backgroundColor:MaterialStatePropertyAll(Colors.redAccent)) ,
onPressed: () {
if(selectPage.text.isNotEmpty){
mapcontroller.fetchMap(selectPage.text);
}else{
Get.snackbar('error','select a page from dropdown menu');
}
},
child:const Text('Get',style: TextStyle(color: Colors.white),)),
FloatingActionButton(
heroTag: 'btn1',
onPressed:(){
Get.to(()=>Emergency());
},
child: const Icon(Icons.emergency_outlined),
)
],
),
),
Positioned(
bottom: 50,
width: MediaQuery.of(context).size.width,
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
style:const ButtonStyle(backgroundColor:MaterialStatePropertyAll(Colors.redAccent)) ,
onPressed: () {
Get.offAll(()=>Nav());
},
child:const Text('Go to Dashboard',style: TextStyle(color: Colors.white),)),
FloatingActionButton(
heroTag: 'btn2',
onPressed: () {
mapcontroller.getlatlong();
},
child:const Icon(Icons.location_on,color: Colors.white,)),
],
),
),
],
),
],
),
),
),
),
GetBuilder<MapController>(builder: (_){
if (mapcontroller.isloading == true) {
return Container(
color: Colors.white.withOpacity(0.5),
child: const Center(
child: CircularProgressIndicator(backgroundColor: Colors.redAccent,color: Colors.white,),
),
);
} else {
return const SizedBox.shrink();
}
}),
],
));
}
}
and my mapcontroller (function is fetchmap at the bottom)(using getx):
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:helping_hand/UI/Map/Mappage.dart';
class MapController extends GetxController{
String locationmessage = 'currentlocation of user';
late String lat ;
late String long ;
Set<Marker>markers={};
#override
void onInit() {
lat = '10.228370';
long ='76.198799';
super.onInit();
}
late GoogleMapController googleMapController;
final Completer<GoogleMapController> _controller = Completer();
Completer<GoogleMapController> get completercontrol => _controller;
static CameraPosition initial = const CameraPosition(target:LatLng(10.228370,76.198799),zoom: 15);
//lower part
Future<Position> getCurrentLocation() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('the location is not enabled');
}
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error(
'location permissions are permanantly denied, cannot grant acess');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'location permissions are permanantly denied, cannot grant acess');
}
return await Geolocator.getCurrentPosition();
}
void liveLocation() {
loadingbar();
LocationSettings settings = const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
Geolocator.getPositionStream(locationSettings: settings)
.listen((Position position) {
lat = position.latitude.toString();
long = position.longitude.toString();
googleMapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(target:LatLng(position.latitude,position.longitude),zoom: 15)));
markers.clear();
markers.add(Marker(markerId:const MarkerId('current user location'),position: LatLng(position.latitude,position.longitude)));
update();
});
loadingbaroff();
}
void getlatlong(){
loadingbar();
getCurrentLocation().then((value){
lat = '${value.latitude}';
long = '${value.longitude}';
googleMapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(target:LatLng(value.latitude,value.longitude),zoom: 15)));
markers.clear();
markers.add(Marker(markerId:const MarkerId('current user location'),position: LatLng(value.latitude,value.longitude)));
update();
if (kDebugMode) {
print(lat);
}
if (kDebugMode) {
print(long);
}
liveLocation();
});
loadingbaroff();
}
void liveLocationToUpload(){
LocationSettings settings = const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
Geolocator.getPositionStream(locationSettings: settings)
.listen((Position position) {
lat = position.latitude.toString();
long = position.longitude.toString();
update();
});
}
//MAP PAGE CONTROLLER CONTROLLS ::::::::::::::
List<DocsForMap> docsformap=[];
Future<void> fetchMap(String page)async {
print('this is starting of fetch map');
loadingbar();
update();
print('after loading bar $isloading');
docsformap.clear();
print('cleared the values of list');
final CollectionReference maps = FirebaseFirestore.instance.collection('map').doc('maps').collection(page);
try{
print('inside try catch');
var data = maps.get();
print('this is dataaa ::::: $data');
maps.get().then((snapshot) => (){
print('inside values::::: $snapshot');
for (var document in snapshot.docs) {
if (kDebugMode) {
print('I AM ACESSING DATA HEREEEEEEEE :::;;;;;;;;;;');
}
if (kDebugMode) {print(document.data());}
}
});
}catch(e){
Get.snackbar('error','error while fetching $page');
print('error happenddddd :::::::: $e');
loadingbaroff();
}
loadingbaroff();
}
bool isloading = false;
void loadingbar() {
isloading = true;
update();
}
void loadingbaroff() {
isloading = false;
update();
}
}
my console :
min=41.46
I/flutter (14542): this is starting of fetch map
I/flutter (14542): after loading bar true
I/flutter (14542): cleared the values of list
I/flutter (14542): inside try catch
I/flutter (14542): this is dataaa ::::: Instance of 'Future<QuerySnapshot<Map<String, dynamic>>>'
W/DynamiteModule(14542): Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule(14542): Considering local module com.google.android.gms.providerinstaller.dynamite:0 and remote module com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller(14542): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putLong(Ljava/lang/Object;JJ)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V (greylist, linking, allowed)
I/System.out(14542): [socket]:check permission begin!
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putLong(Ljava/lang/Object;JJ)V (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getLong(Ljava/lang/Object;J)J (greylist,core-platform-api, linking, allowed)
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object; (greylist, linking, allowed)
I/System.out(14542): [socket]:check permission begin!
I/System.out(14542): [socket]:check permission begin!
I/System.out(14542): [socket]:check permission begin!
D/ViewRootImpl(14542): setSurfaceViewCreated, created:false
D/Surface (14542): Surface::disconnect(this=0x7500239000,api=-1)
D/Surface (14542): Surface::disconnect(this=0x755e735000,api=1)
I/BufferQueueProducer(14542): [SurfaceTexture-0-14542-4](this:0x74a100b000,id:7,api:1,p:14542,c:14542) disconnect(P): api 1
I/BufferQueueProducer(14542): [ImageReader-1080x2340f1m3-14542-0](this:0x74cfcc8800,id:0,api:1,p:14542,c:14542) queueBuffer: fps=0.05 dur=600096.19 max=599491.31 min=10.40
I/BufferQueueProducer(14542): [ImageReader-1080x2340f1m3-14542-2](this:0x74cf08b800,id:3,api:1,p:14542,c:14542) queueBuffer: fps=0.05 dur=600100.68 max=599496.03 min=9.76
I/GED (14542): ged_boost_gpu_freq, level 100, eOrigin 2, final_idx 29, oppidx_max 29, oppidx_min 0
W/le.helping_han(14542): Accessing hidden method Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V (greylist, linking, allowed)
D/Surface (14542): Surface::disconnect(this=0x754e09a000,api=1)
E/libprocessgroup(14542): set_timerslack_ns write failed: Operation not permitted
Try with following code for method fetchMap
Future<void> fetchMap(String page) async {
print('this is starting of fetch map');
loadingbar();
update();
print('after loading bar $isloading');
docsformap.clear();
print('cleared the values of list');
final CollectionReference maps = FirebaseFirestore.instance.collection('map').doc('maps').collection(page);
try{
print('inside try catch');
var data = await maps.get();
print('this is dataa ::::: $data');
for (var document in data.docs) {
if (kDebugMode) {
print('I AM ACESSING DATA HEREEEEEEEE :::;;;;;;;;;;');
}
if (kDebugMode) {print(document.data());}
}
} catch(e) {
Get.snackbar('error','error while fetching $page');
print('error happenddddd :::::::: $e');
}
loadingbaroff();
}

Flutter: How to pass array data from json Future< to Widget

Being new to flutter, I'm learning and stumbling on the go.
I am trying to pass an array that I have received from json into an already waiting widget structure but can't quite seem to get the connection.
Here's the sample code:
class Products extends StatefulWidget {
#override
_ProductsState createState() => _ProductsState();
}
class _ProductsState extends State<Products> {
#override
void initState() {
_getProducts();
}
Future<List<Single_prod>> _getProducts() async {
var url = "";
var data = await http.get(url);
var jsonData = json.decode(data.body) as Map<String, dynamic>;
//print(jsonData.toString());
//jsonData.forEach((k, v) => print("Key : $k, Value : $v"));
List<Single_prod> items = [];
jsonData.forEach((k, v){
Single_prod item = Single_prod(v["error"], v["id"], v["name"], v["price"], v["image"]);
items.add(item);
});
//print(items.length);
return items; <---Tring to pass this to Widget build but not recognized.....
}
#override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: items.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (BuildContext context, int index){
return Single_prod(
prod_err: items[index]['error'], <--- This items array is not recognized
prod_id: items[index]['id'],
prod_name: items[index]['name'],
prod_price: items[index]['price'],
prod_image: items[index]['image'],
);
});
}
}
The items array is not recognized in the widget
Here is the rest of the code:
class Single_prod extends StatelessWidget {
final prod_err;
final prod_id;
final prod_name;
final prod_price;
final prod_image;
Single_prod({
this.prod_err,
this.prod_id,
this.prod_name,
this.prod_price,
this.prod_image,
});
#override
Widget build(BuildContext context) {
return Card(
child: Hero(
tag: prod_name,
child: Material(
child: InkWell(
onTap: () => Navigator.of(context).push(new MaterialPageRoute(
// here we are passing the values of the products to the details page
builder: (context) => new ProductDetails(
prod_detail_name: prod_name,
prod_detail_image: prod_image,
prod_detail_id: prod_id,
prod_detail_price: prod_price,
))),
child: GridTile(
footer: Container(
height: 40.0,
color: Colors.white70,
child: ListTile(
leading: Text(prod_name, style: TextStyle(fontWeight: FontWeight.bold),),
title: Text(
prod_price,
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w800, fontSize: 12),
),
/*subtitle: Text(
prod_oldprice,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w800, fontSize: 11, decoration: TextDecoration.lineThrough),
),*/
),
),
child: Image.asset(prod_image,
fit: BoxFit.cover,),
),
),
),
),
);
}
}
How does the upper code connect with the lower code?
Thanks in advance.
First, look at the scope of your 'items' variable: it is defined in getItems() function, and it is not visible outside the function. So, first thing: make it class level property.
Next - your initState will call your method. Method is async, and the way to handle it in initState to use '.then' on the Future returned by your method. What you want to do here is: once the future completes, you want to set your class level variable to hold the value returned by _getProduct() function.
And finally - this is very important to understand: you don't call build method yourself - flutter framework does it for you. Now, flutter does not have a magic way of knowing when you changed the data - it won't observe your code, so you need to tell it somehow that your state object changed, and it requires rebuild. You do it by calling setState() function.
I think you have another issue here actually: you already bulit your Single_prod widget in _getProduct(), no need to build it again. I tried to correct this also.
Try this (I didn't compile it so it might have few errors):
class Products extends StatefulWidget {
#override
_ProductsState createState() => _ProductsState();
}
class _ProductsState extends State<Products> {
List<Single_prod> items = [];
#override
void initState() {
super.initState();
_getProducts().then( (result) {
setState(() {
items=result;
}
});
}
Future<List<Single_prod>> _getProducts() async {
var url = "";
var data = await http.get(url);
var jsonData = json.decode(data.body) as Map<String, dynamic>;
//print(jsonData.toString());
//jsonData.forEach((k, v) => print("Key : $k, Value : $v"));
List<Single_prod> items = [];
jsonData.forEach((k, v){
Single_prod item = Single_prod(v["error"], v["id"], v["name"], v["price"], v["image"]);
items.add(item);
});
//print(items.length);
return items;
}
#override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: items.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (BuildContext context, int index){
return items[index];
});
}
}

Looping Inside Stack Widget Flutter

I have a problem right now
I need to use StreamBuilder to get all the data from my database and then build every data into a widget with position in it.
Because I use position, I need to use Stack as a parent widget.
But the problem is I can't use ListView builder to loop the snapshot data
Is there any way to loop inside so I can return the widget?
Stack(
children: <Widget>[
Container(
color: Colors.white,
),
StreamBuilder(
// initialData: {'handler': "handler"},
stream: mapPlacementStream.stream,
builder: (context, snapshotPlacement) {
dataPlacement = snapshotPlacement.data;
if(!snapshotPlacement.hasData){
return const Text('Connecting...');
}
else{
return new StreamBuilder(
// initialData: {0: true},
stream: mapStateStream.stream,
builder: (context, snapshotState) {
dataState = snapshotState.data;
if(!snapshotState.hasData){
return const Text('Connecting...');
}
else{
return ParkPainter(
1,
20,
20,
1,
true
);
}
);
}
}
),
],
)
On Else I return the ParkPainter to see if it can print the ParkPainter (the widget with position)
It works

Getting Data from cloud Firestore and showing for flutter app

I have a profile screen. and getting data from the cloud store and showing in the profile screen.
I guess there is no problem while retrieving data but the problem is while showing. I don't know how I mess up?
Now the error is only showing "Loading" Text.
Help me
class Profile extends StatefulWidget {
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
bool userFlag = false;
var users;
#override
void initState() {
// TODO: implement initState
super.initState();
UserManagement().getData().then((QuerySnapshot docs){
userFlag = true;
users = docs.documents[0].data;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Profile'),
),
body: Container(
padding: EdgeInsets.all(50),
child: Column(
children:<Widget>[
name(),
],
),
),
);
}
Widget name() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
"Name",
style: TextStyle(fontWeight: FontWeight.w600,fontSize: 18),
),
SizedBox(
width: 45,
),
userFlag ? Text(users['Name'],
style: TextStyle(fontWeight: FontWeight.w400,fontSize: 18),
)
:Text('Loading'),
],
),
);
}
for getting Data i have:
getData(){
return Firestore.instance
.collection('users').getDocuments();
}
I get and Use Data that way:
QuerySnapshot Users = await _fs
.collection("users")
.getDocuments();
It will give you all the users in the users collection.
so for retrieving one user in specific I use a "for loop".
String myEmail = "email#gmail.com";
String username;
for (var user in users.documents) {
if ( myEmail == user.data["email"]){
// you have all the field for the user using "myEmail".
username = user.data["username"];
} else {
print("There is no User with this email");
}
}
But I think there might be a better way to do it.
This error is because, You should initialize your user variable like
var users = {}; instead of
var user;

REST API in flutter

I have a project in which I have a Python database and I have a Flutter ui.
Is there anyway I can use the REST API to connect them? My teammates who do the backend state that their database will use the REST API, so it would be useful if I can do that.
Yes, you can easily use REST API's with Flutter.
Dart offers an http package for easy HTTP request and there are others available on Dart Pub.
With the http package, you can even integrate your REST API request into the build tree very easily using a FutureBuilder:
FutureBuilder(
future: http.get('https://your-rest-api-domain.xyz/get-images?amount=5'),
builder: (context, snapshot) {
// you can easily work with your request results in here and return a widget
},
)
As cricket_007 mentioned in a comment, Flutter also provides a cookbook entry on this topic.
Simple cade for calling REST API and display in a listview.
Step 1:
Create a model class like this
class ItemSubCat{
final String ItemCode;
final String ItemName;
ItemSubCat(
{this.ItemCode, this.ItemName});
factory ItemSubCat.fromJson(Map<String, dynamic> parsedJson){
return ItemSubCat(
ItemCode: parsedJson['ItemCode'],
ItemName: parsedJson['ItemName']);
}
}
Step 2:
List<ItemSubCat> parsePosts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<ItemSubCat>((json) => ItemSubCat.fromJson(json)).toList();
}
Future<List<ItemSubCat>> fetchsubcat(http.Client client) async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile||connectivityResult == ConnectivityResult.wifi) {
final response = await client.get('Your Api Url');
//print(response.body);
return compute(parsePosts, response.body);
} else {
Toast.show(message: "Please check your network conenction", duration: Delay.SHORT, textColor: Colors.black);
}
}
Step 3:
class ItemSubCategory extends StatelessWidget {
final String ItemCatCode;
ItemSubCategory({Key key, #required this.ItemCatCode}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
iconTheme: IconThemeData.fallback(),
title: Text('Category', style: TextStyle(color: Colors.black)),
centerTitle: true,
),
body: FutureBuilder<List<ItemSubCat>>(
future: fetchsubcat(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? GridViewPosts(items: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
Step 4:
class GridViewPosts extends StatelessWidget {
final List<ItemSubCat> items;
GridViewPosts({Key key, this.items}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: new GridView.builder(
itemCount: items.length,
shrinkWrap: true,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int position) {
return new Column(
children: <Widget>[
Divider(height: 0.0),
cardDetails(--You pass your data to listitems--),
],
);
})
);
}
}
Here you design your widget for a list item (cardDetails)

Resources