I have list, I want to save in sharepreferences,
setString('key',json.encode(temporaryData));
When I try to get this value, only show Instance of Future<dynamic>
but when i print that json.encode show it value
[{"name":"Stranger","birthDate":"","idCardNum":"-1","currentTime":1593598133479,"imageFlag":1,"imageName":"-1_1_1593598133479.png","type":-1,"tempratrue":"36.3","mask":0}]
Future<SharedPreferences> storage() {
return SharedPreferences.getInstance();
}
void setTempData(String temp) async {
SharedPreferences sharedPreferences = await storage();
await sharedPreferences.setString('datas', temp);
}
getTempData(String key) async {
SharedPreferences sharedPreferences = await storage();
await sharedPreferences.get(key);
}
_getTemp() async {
DateTime start = DateTime.now().subtract(Duration(seconds: 5));
DateTime end = DateTime.now();
Map data = {'pass': '123456', 'startTime': '$start', 'endTime': '$end'};
var response = await http.post('$urlApiQr:8080/newFindRecords', body: data);
var jsonData = json.decode(response.body);
var jsEnc = json.encode(response.body);
TempJson tempJson = TempJson.fromJson(jsonData);
var parse = json.decode(tempJson.config);
setState(() {
dataList = parse;
temporaryData = dataList.toSet().toList();
setTempData(json.encode(temporaryData));
//try to print value
print('$start and $end');
print(parse);
print(getTempData('datas'));
});
}
Is there a solution to my problem?
UPDATE 2.0
you have to add await anywhere your are requesting value from a Future.. as the below method return a Future as you can see from your error, just add await keyword from where you are requesting a value,
for example
print(await getTempData(key));
UPDATE
return keyword missing
getTempData(String key) async {
SharedPreferences sharedPreferences = await storage();
//you missed the return keyword here
return await sharedPreferences.get(key);
}
original answer
dont miss the await keyword
var thestring = await sp.getString('the_key');
var theJsonObj = json.decode(thestring);
this is my assumption, please post more code
Related
I have a Stream which seems to work perfectly fine: Every print statement you see in the stream is getting printed. Also when calling if(snapshot.hasData) it apparently is true. But still, my stream only returns the following: AsyncSnapshot<List<dynamic>>(ConnectionState.done, [], null, null).
What do I need to change in order to be able to access the Data in my retVal variable?
Stream<List>? roomsListStream() {
try {
List<RoomsListModel> retVal = [];
print("userId: $userId");
var rooms = FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots();
print("rooms: $rooms");
rooms.forEach((element) {
element.docs.forEach((element) {
print("element: $element");
var room = element.data();
print("room: $room");
var roomId = room["roomId"];
var otherUserId =
room["users"].firstWhere((element) => element != userId);
var lastMessage = room["latestMessage"];
var lastMessageTime = room["latestMessageTime"];
print("otherUserId: $otherUserId");
getOtherUser(otherUserId).then((value) {
print("value: $value");
var avatar = value["photoUrl"];
var name = value["name"];
retVal.add(RoomsListModel(
roomId: roomId,
otherUserId: otherUserId,
avatar: avatar,
name: name,
lastMessage: lastMessage,
lastMessageTime: lastMessageTime));
});
});
});
return Stream.value(retVal);
} catch (e) {
print("Error: $e");
}
}
Try:
var rooms = await FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots();
Code
print("Before : ${GetStorage().read("XXX")}");
GetStorage().write("XXX", 1);
print("After : ${GetStorage().read("XXX")}");
This is my Code. Every time I run the App, the Output is
Before : null
After : 1
Why is the storage data getting cleared everytime I restart the App? I thought this was an alternative to SharedPreference which works just fine. Have I missed something?
Before anything, initialize the package, normally I do this on main.dart
main() async {
await GetStorage.init();
}
Create an instance from GetStorage, I always put a name on the box, if not it will put "GetStorage" by default. It needs to have a name so it can retrieve your data.
GetStorage getStorage = GetStorage('myData');
After that you can write and retrieve data from it, I recommend you to "await" all reads and writes.
await getStorage.write('XXX', 1);
var a = await getStorage.read('XXX');
print(a); /// 1
I recommend you to put a name on the box according to what you are storing.
You should await for GetStorage.init().
void main() async {
await GetStorage.init();
print("Before : ${GetStorage().read("XXX")}");
GetStorage().write("XXX", 1);
print("After : ${GetStorage().read("XXX")}");
}
final _userBox = () => GetStorage('User');
class UserPref {
void call(){
_userBox.call()..initStorage;
}
dynamic setValueInt(String key, int value) {
return 0.val(key, getBox: _userBox).val = value;
}
String setValue(String key, String value) {
return ''.val(key, getBox: _userBox).val = value;
}
dynamic getValueInt(String key) {
return (-1).val(key,getBox: _userBox).val;
}
dynamic getValue(String key) {
return ''.val(key,getBox: _userBox).val;
}
void setUser(User user) {
''.val('uname', getBox: _userBox).val = user.uname ?? '';
(-1).val('gender', getBox: _userBox).val = user.gender ?? -1;
''.val('born', getBox: _userBox).val = user.born.toString();
true.val('enabled', getBox: _userBox).val = user.enabled ?? true;
}
User getUser() {
final String? uname = ''.val('uname',getBox: _userBox).val;
final int? gender = (-1).val('gender',getBox: _userBox).val;
final DateTime? born = ''.val('born',getBox: _userBox).val == '' ? null : DateTime.parse(''.val('born',getBox: _userBox).val);
final bool? enabled = true.val('enabled',getBox: _userBox).val;
return User(
uname: uname,
gender: gender,
born: born,
enabled: enabled,
);
}
}
///INIT:
#override
void initState() {
//The init function must be written separately from the read/write function due to being asynchronous.
UserPref().call();
}
//OR
Future<void> main() async {
//await GetStorage.init();
UserPref().call();
}
///USAGE:
class MyStatefulWidget extends StatefulWidget {
final Users prefUser = UserPref().getUser();
...
}
//OR
#override
Widget build(BuildContext context) {
final Users prefUser = UserPref().getUser();
return ...;
}
I want to use a string in this function that has the phone number of the device.
I get the phone number with this:
Future<void> initMobilNumberState() async {
if (!await MobileNumber.hasPhonePermission) {
await MobileNumber.requestPhonePermission;
return;
}
String mobileNumber = '';
try {
mobileNumber = await MobileNumber.mobileNumber;
_simCard = await MobileNumber.getSimCards;
} on PlatformException catch (e) {
debugPrint("Failed to get mobile number because of '${e.message}'");
}
if (!mounted) return;
setState(() {
var re = RegExp(r'\+[^]*');
_mobileNumber = mobileNumber.replaceRange(0, 3, ''.replaceAll(re, '+'));
});
}
My problem is that if I want to print _mobileNumber or use it in http.get I get null or a error with "Invalid Arguments"
Future<http.Response> _fetchSampleData() async {
String s = _mobileNumber;
print(s);
return http.get('http://test.php?TestPhone=' + _mobileNumber);
}
Future<void> getDataFromServer() async {
final response = await _fetchSampleData();
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
_list = data.values.toList();
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
showAlertNoInternet(context);
print('Failed to load data from server');
}
}
Where is my mistake?
The problem is that I want to call the phone number before it has even been fetched. So this always resulted in null. I fixed this by fetching the number when I start the app with all the other data I need.
im trying to make this app to learn the methods to use in Firebase, now, im using Cloud Firestore + Storage, but im getting this error:
Exception has occurred.
FirebaseException ([firebase_storage/object-not-found] No object exists at the desired reference.)
im soo new on firebase so i dont know what to do... also there were a lot of updates and changes and some replies in other posts are deprecated ...
Future<void> uploadPic(File foto) async {
final Reference postImageRef = FirebaseStorage.instance.ref().child('Post Images');
var timeKey = DateTime.now();
await postImageRef.child(timeKey.toString() + "jpg").putFile(foto)
.whenComplete(() async { //IM GETTING THE ERROR HERE
await postImageRef.getDownloadURL().then((value) { //IM GETTING THE ERROR HERE
posts.imageUrl = value;
});
});
return posts.imageUrl;
}
and here is the submit of the button "save"
void _submit() async {
if (!formKey.currentState.validate()) return null;
formKey.currentState.save();
uploadPic(foto);
subirPost(posts);
print(posts.datetime);
mostrarToast('Producto guardado');
}
The error here is that you do not wait for the downloaded image link to return to you using this method:
Note: If you want to upload and write at the same time, you must wait for the completion of the lifting and then write.
1- First, create an external file that contains all the related services in Firebase, let's say its name is Api, and add this method in it:
static Future<dynamic> postFile(
{#required File imageFile, #required String folderPath}) async {
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
Reference reference =
FirebaseStorage.instance.ref().child(folderPath).child(fileName);
TaskSnapshot storageTaskSnapshot =await reference.putFile(imageFile);
print(storageTaskSnapshot.ref.getDownloadURL());
var dowUrl = await storageTaskSnapshot.ref.getDownloadURL();
return dowUrl;
}
2- When the image is uploaded, this method will return you the link to download the image in Firebase, store it in the object as described below:
String imgUrl = await Api.postFile(
imageFile: image,
folderPath: 'image');
if (imgUrl != null) {
posts.imageUrl = imgUrl;
///Type here the command that will write to the firestore
}
Check Out This Working Code
Need An uuid Package: https://pub.dev/packages?q=uuid
File _image;
final pickedFile = await ImagePicker()
.getImage(source: ImageSource.camera, imageQuality: 80);
final String filePath = pickedFile != null ? pickedFile.path : '';
if (filePath.isNotEmpty) {
_image = File(filePath);
if (_image != null) {
if (_image != null) {
final Reference sref = storageReference
.child('chat_multimedia/images/')
.child(uuid.v4());
final UploadTask storageUploadTask = sref.putFile(
_image,
SettableMetadata(
contentType: mime(basename(_image.path)),
),
);
if (storageUploadTask.snapshot.state == TaskState.success) {
final String url = await sref.getDownloadURL();
print('The download URL is ' + url);
} else if (storageUploadTask.snapshot.state == TaskState.running) {
storageUploadTask.snapshotEvents.listen((event) {
percentage = 100 *
(event.bytesTransferred.toDouble() /
event.totalBytes.toDouble());
print('THe percentage ' + percentage.toString());
});
} else {
print('Enter A valid Image');
}
await storageUploadTask.whenComplete(() async {
final String downloadUrl = await sref.getDownloadURL();
});
}
}
}
I have a custom class that fetches data from the database, that returns Future<List<Line>>, which lies in line_list.dart files :
Future<List<Line>> fetchingLinesData() async {
List<Line> lineList = [];
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'main.db');
Database database = await openDatabase(path, version: 1);
database.transaction((tnx) async {
dbRef.child('line').once().then((DataSnapshot dataSnapshot) async {
dataSnapshot.value.forEach((key, value) async {
List<Station> inLineStations = [];
for (var i = 0; i < 100; i++) {
if (value["station_$i"] != null) {
List<Map> stations = await tnx.rawQuery("SELECT * FROM Station");
stations.forEach((s) {
if (s['stationName'] == value["station_$i"]) {
Station stationInstance = Station(
key: s['key'],
cityName: s['cityName'],
stationName: s['stationName'],
stationLongitude: s['stationLongitude'],
stationLatitude: s['stationLatitude']);
inLineStations.add(stationInstance);
}
});
}
}
Line lineInstance = Line(
startStation: value['start_station'],
endStation: value['end_station'],
inLineStations: inLineStations,
notes: value['notes'],
price: value['price'],
transportationType: value['transportation_type']);
lineList.add(lineInstance);
});
});
});
return lineList;
}
}
and then in my main.dart widget, I have this :
List<Line> allLines = [];
I want to do something like this :
allLines = LinesList().fetchingLinesData();
But of course, it gives me an error as am trying to assign Future<List<Line>> to List<Line>
how to do it?
You have to await for future to complete.
allLines = await LinesList().fetchingLinesData();
You would just put the code below in a async function make main async and make your code
allLines = await LinesList().fetchingLinesData();