I'm trying to get a specific field called "specie" from a document in a Firebase collection. I am trying as follows but I have an error of type 'Future ' is not a subtype of type 'String'. What am I doing wrong?
Repository method:
getSpecie(String petId) {
Future<DocumentSnapshot> snapshot = petCollection.document(petId).get();
return snapshot.then((value) => Pet.fromSnapshot(value).specie);
}
Entity method:
factory Pet.fromSnapshot(DocumentSnapshot snapshot) {
Pet newPet = Pet.fromJson(snapshot.data);
newPet.reference = snapshot.reference;
return newPet;
}
factory Pet.fromJson(Map<String, dynamic> json) => _PetFromJson(json);
Pet _PetFromJson(Map<String, dynamic> json) {
return Pet(json['name'] as String,
specie: json['specie'] as String);
}
I found a solution. No needed fromJson() method, I only changed the repository method:
Future<String> getSpecie(String petId) async {
DocumentReference documentReference = petCollection.document(petId);
String specie;
await documentReference.get().then((snapshot) {
specie = snapshot.data['specie'].toString();
});
return specie;
}
Try this..
getSpecie(String petId) async{
Future<DocumentSnapshot> snapshot = await petCollection.document(petId).get();
return snapshot.then((value) => Pet.fromSnapshot(value).specie);
}
This is how I learned to get documents from firestore
https://medium.com/#yasassandeepa007/how-to-get-sub-collection-data-from-firebase-with-flutter-fe1bda8456ca
Related
This question already has answers here:
"The operator '[]' isn't defined" error when using .data[] in flutter firestore
(6 answers)
Closed 3 months ago.
I would like to recover data in my firebase database but it does not work.
void _userData() async {
DocumentReference documentReference = FirebaseFirestore.instance
.collection("Users")
.doc("axelduf2006#gmail.com");
documentReference.get().then((datasnapshot) {
data = datasnapshot.data;
return print("pseudo: ${data['pseudo']}");
});
}
my log console
I would like to know the value contained in pseudo in my database.
Change data with data() to get the Map<String, dynamic> of your document.
void _userData() async {
DocumentReference documentReference = FirebaseFirestore.instance
.collection("Users")
.doc("axelduf2006#gmail.com");
documentReference.get().then((datasnapshot) {
data = datasnapshot.data() as Map<String, dynamic>; // set it like this
return print("pseudo: ${data['pseudo']}");
});
}
Passing the data will pass the definition of Map<String, dynamic> Function ( () => Map<String, dynamic> ), not the actual Map<String, dynamic> of the document data.
I am getting the Error "NoSuchMethodError: The method '[]' was called on null." from my stream. I tried to change my code several times and added print statements, which get printed correctly, but my Stream ends up returning an error, which is the one from the subject line. Any idea why? How can I Fix the error?
This is the result of the print data statement:
data:
{
userId1: 59jTMEbvqFd8C8UhInksauAVNk63,
userId2: 2ssfDEPhPhcIwInUWdlm0ReH5RZ2,
latestMessageTime: Timestamp(seconds=1667140814, nanoseconds=334000000),
lastMessageSenderId: 59jTMEbvqFd8C8UhInksauAVNk63,
created_at: 2022-10-26 19:44:13.793275,
latestMessage: TEST 3,
roomId: Qv30s8kATJbFJIWRdBEo
}
.
Stream<RoomsListModel> roomsStream() async* {
try {
// get all active chats
var rooms = await FirebaseFirestore.instance
.collection("rooms")
.where("users", arrayContains: userId)
.orderBy("latestMessageTime", descending: true)
.snapshots();
print("rooms: $rooms");
// get Other user details
await for (var room in rooms) {
for (var doc in room.docs) {
var data = doc.data() as Map<String, dynamic>;
print("data: $data");
var otherUser = await getOtherUser(
data["users"][0] == userId ? data["users"][1] : data["users"][0]);
print("otherUser: $otherUser");
yield RoomsListModel(
roomId: doc.id,
userId: otherUser["user id"],
avatar: otherUser["photoUrl"],
name: otherUser["name"],
lastMessage: data["latestMessage"],
lastMessageTime: data["latestMessageTime"]);
}
}
} catch (e) {
print("Error: $e");
}
}
.
Future getOtherUser(String id) async {
// get other user profile
var user = await FirebaseFirestore.instance
.collection("users")
.doc(id)
.get()
.then((value) => value.data()) as Map<String, dynamic>;
// return other user profile
return user;
}
change this:
var otherUser = await getOtherUser(
data["users"][0] == userId ? data["users"][1] : data["users"][0]);
to this:
var otherUser = await getOtherUser(
data["userId1"] == userId ? data["userId2"] : data["userId1"]);
In this code, I am passing the fetched data from the PHP API and it
is parsed and mapped by the JSON function successfully but I have
noticed that it does not return the value to the future builder which
is originally calling the fetchJson function and the following error
is displayed when i debug and the debugger reaches the variable alpha
in the future Builder below and then shows this error:
<error: org-dartlang-debug:synthetic_debug_expression:1:1: Error: The
getter '_chainSource' isn't defined for the class 'Future'.
'Future' is from 'dart:async'. Try correcting the name to the name of an existing getter, or defining a getter or field named
'_chainSource'.
_chainSource
<error: org-dartlang-debug:synthetic_debug_expression:1:1: Error: The
getter '_hasError' isn't defined for the class 'Future'.
'Future' is from 'dart:async'. Try correcting the name to the name of an existing getter, or defining a getter or field named
'_hasError'.
_hasError ^^^^^^^^^>
Future<List<BodyModel>> fetchJson(http.Client client, String? id) async {
final response = await client.get(
Uri.parse(uri2),
);
if (response.statusCode == 200) {
String jsonData = response.body;
print(response.body);
//print(jsonEncode(response.body));
List<BodyModel> alpha = responseJSON(jsonData);
//print(alpha.toSet());
//bravo = alpha;
return alpha;
} else {
throw Exception('We were not able to successfully download the json data.');
}
}
List<BodyModel> responseJSON(String response) {
final parse = jsonDecode(response).cast<Map<String, dynamic>>();
print(parse.toString());
final resp =
parse.map<BodyModel>((json) => BodyModel.fromJson(json)).toList();
print(resp);
return resp;
}
onTap: () {
id_get = model.id;
final alpha = fetchJson(http.Client(), id_get);
print(alpha);
FutureBuilder<List<BodyModel>>(
future: fetchJson(http.Client(), id_get),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ViewScreen(snapshot.data!);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
} else {
return CircularProgressIndicator();
}
},
);
},
import 'package:flutter/material.dart';
class BodyModel {
String body;
String title;
BodyModel({
required this.body,
required this.title,
});
factory BodyModel.fromJson(Map<String, dynamic> jsonData) {
return BodyModel(
body: jsonData['body'].toString(),
title: jsonData['title'].toString(),
);
}
}
enter image description hereFuture dynamic not working please help trying to make a weather app
class WeatherModel {
Future<dynamic> getLocationWeather() async{
Location location = Location();
await location.getCurrentLocation();
Networkhelper networkhelper = Networkhelper(
'$openWeatherMapURL
lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');
var weatherData = await networkhelper.getData();
return weatherData;
}}
your code should look like this:
Confirm your URL matches mine. Seems like you're missing ?.
Future<dynamic> getLocationWeather() async {
Location location = Location();
await location.getCurrentLocation();
NetworkHelper networkHelper = NetworkHelper(
url: // if you used a positional argument.
'$openWeatherMapURL?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');
var weatherData = await networkHelper.getData();
return weatherData;
}
class Resistencia100{
int id;
double r_pos1;
double r_pos2;
double r_pos3;
double r_pos4;
double r_pos5;
Resistencia100({
this.id, this.r_pos1, this.r_pos2, this.r_pos3, this.r_pos4,
this.r_pos5
});
Map<String, dynamic> toMap() => {
"id": id,
"r_pos1": r_pos1,
"r_pos2": r_pos2,
"r_pos3": r_pos3,
"r_pos4": r_pos4,
"r_pos5": r_pos5,
};
factory Resistencia100.fromMap(Map<String, dynamic> json) => new Resistencia100(
id: json["id"],
r_pos1: json["r_pos1"],
r_pos2: json["r_pos2"],
r_pos3: json["r_pos3"],
r_pos4: json["r_pos4"],
r_pos5: json["r_pos5"],
);
}
This is my Model class Resistencia100, Now we will see how I request the data through my get method
Future<List<Resistencia100>> getAllResistencia100() async {
final db = await database;
var response = await db.query("Resistencia100");
List<Resistencia100> list = response.map((c) => Resistencia100.fromMap(c)).toList();
print("Cantidad ID: "+list[0].id.toString());
print("Cantidad r_pos1: "+list[0].r_pos1.toString());
print("Cantidad r_pos2: "+list[0].r_pos2.toString());
print("Cantidad r_pos3: "+list[0].r_pos3.toString());
print("Cantidad r_pos4: "+list[0].r_pos4.toString());
print("Cantidad r_pos5: "+list[0].r_pos5.toString());
return list;
}
The information is coming correctly to the method, now I try to extract that information and the error is coming.
List <Resistencia100> resistencia100 = new List<Resistencia100>();
Future<List<Resistencia100>> getResistencia100() async {
await ClientDatabaseProvider.db.getAllResistencia100();
}
void validate() async {
resistencia100 = await getResistencia100();
print("RESISTENCIA ID: "+resistencia100[0].id.toString());
}
The truth is that I don't understand the reason for the error very well, I hope you can understand, I will leave the textual error in the following lines, this is generated in the "print".
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
Receiver: null
Tried calling: [](0)
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _ConfigConcretoState.validate (package:entremuros/vistas/configconcreto.dart:282:44)
Your method getResistencia100() is not returning anything. So at validate() your variable resistencia100 is transforming into a null after await the getResistencia100()
A solution is change the getResistencia100(), adding a return statement
Future<List<Resistencia100>> getResistencia100() async {
return await ClientDatabaseProvider.db.getAllResistencia100();
}