I am working on an app in flutter which requires me to store and retrieve keys stored in firebase/firestore. Currently I am reading all the keys as a stream after following few tutorials. Although I do not want to read it as a stream. I just want to read the current value of the keys once and store those keys in my Provider class
named ActivationKeyPoolProvider
. I want to programmatically call a function which reads all the keys stored on firestore and then do not listen to the stream. Finally I want to be able to change the status of the key from true to false. Currently I am able to do this as shown in the onTap Function
inside _buildListItem
. I found this function from the flutter youtube channel and I apologise because I do not understand that part much. I usually do not just copy paste without understand but this time I did. I am not an expert in flutter yet and barely started with Firestore.
Following is a stripped down code that I am currently using and a key structure that I have on firestore:
Firestore collection
// -> collection: alphaNumericKey
// ->document: 1
// -> key : /15 character long key/
// -> status : /true or false/
// ->document: 2
// -> key : /15 character long key/
// -> status : /true or false/
// ->document: 3
// -> key : /15 character long key/
// -> status : /true or false/
// ...........
Key Page
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import '../Provider/activation_key_pool_provider.dart';
class KeyActivationPage extends StatefulWidget {
const KeyActivationPage({Key? key}) : super(key: key);
static const routeName = '/KeyActivationPage';
@override
_KeyActivationPageState createState() => _KeyActivationPageState();
}
class _KeyActivationPageState extends State<KeyActivationPage> {
final _keyController = TextEditingController();
bool _firebaseSuccess = false;
bool _keysVisible = false;
String? key;
@override
void initState() {
super.initState();
Firebase.initializeApp().whenComplete(() {
print("firebase initialised");
Future.delayed(Duration(seconds: 2), () {
setState(() {
_firebaseSuccess = true;
});
});
});
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
void dispose() {
super.dispose();
_keyController.dispose();
}
Widget _buildListItem({
required BuildContext context,
required DocumentSnapshot document,
required int length,
required int currentIndex,
}) {
ActivationKeyPoolProvider.addKey(
key: document['alphaKey'],
status: document['status'],
);
if (currentIndex == length - 1) {
//ActivationKeyPoolProvider.printAllKeys();
}
return _keysVisible
? ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Text(
document['alphaKey'],
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
Expanded(
child: Container(
padding: EdgeInsets.all(10.0),
child: Text(
document['status'].toString(),
style: Theme.of(context).textTheme.headline6,
),
),
)
],
),
onTap: () {
// Responsible to change the state of the key
// Do not quite understand how this works yet
FirebaseFirestore.instance.runTransaction((transaction) async {
DocumentSnapshot freshSnap = await transaction.get(document.reference);
transaction.update(freshSnap.reference, {
'status': document['status'] ? false : true,
});
});
print('should change active status');
},
onLongPress: () {
//Do something
},
)
: Container();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Center(
child: Stack(
children: <Widget>[
// Keys for debug
_firebaseSuccess
? StreamBuilder(
stream: FirebaseFirestore.instance
.collection('alphaNumericKey')
.snapshots(),
builder: (context, snapshot) {
ActivationKeyPoolProvider.setListEmpty();
AsyncSnapshot _snapshot;
if (!snapshot.hasData) return const Text('loading...');
_snapshot = snapshot;
return ListView.builder(
itemExtent: 50.0,
itemCount: _snapshot.data.docs.length,
itemBuilder: (context, index) {
return _buildListItem(
context: context,
document: _snapshot.data.docs[index],
length: _snapshot.data.docs.length,
currentIndex: index,
);
},
);
},
)
: Container(
child: Center(
child: Text(
'Loading keys',
style: Theme.of(context).textTheme.bodyText1,
)),
),
],
),
),
);
}
}