How to sequentially send requests to the server? - flutter

I have a List, and I need to send each element of this List to the server sequentially. And if the answer is with an error, then do not continue sending, but display an error. I am trying to use
await Future.wait([]);
but I do not quite understand how to complete the send on failure, and how to iterate over the elements.
To iterate over elements through .forEach(element) {}
The compiler throws an error: The argument type 'List' can't be assigned to the parameter type 'Iterable<Future>'
Here is what I am trying to do:
await Future.wait([
state.revisionFill.forEach((element) {
var successOrFail = await ContainerExpire.call(ContainerExpireParams(token: token, entity: element.entity));
})
]);
I'm new and don't fully understand async/sync requests in flutter. Tell me which direction to study.
How to complete the next send if it fails?

This seems to be what you're looking for:
for (var element in state.revisionFill) {
var successOrFail = await ContainerExpire.call(ContainerExpireParams(token: token, entity: element.entity));
if (successOrFail.hasFailed()) {
//add code for some possible error handling
break;
}
}
I am assuming that based on the value of successOrFail you can tell whether or not an error occured. Basically after each request you check for the status, and break on an error. You can add logic for displaying your error message.

Related

forEach not working in my map iteration. Any experts here?

I'm working with an app in Flutter that writes data to a Firebase database that I created and then reads and displays it in a list view in my app. Currently the app writes the data correctly and also reads it and prints it to the command line. However, when I code the bit that's supposed to then take that data and dump it into a list that can be printed in list view I get the following error when trying to iterate it from a map to a list using a forEach command. The error is "The method 'forEach' can't be unconditionally invoked because the receiver can be 'null'."
I've even tried adding '!' to force it to run since I know it's not null but it still won't work. Any ideas? The code for that section is below. Thanks in advance!
_ListViewReadPageState() {
// load all students from firebase database and display them in list view
FirebaseDatabase.instance.ref("students").once()
.then((databaseEvent) {
print("Successfully loaded the data");
print(databaseEvent);
print("Key:");
print(databaseEvent.snapshot.key);
print("value:");
print(databaseEvent.snapshot.value);
print("Iterating the value map");
var studentTmpList = [];
databaseEvent.snapshot.value.forEach((k, v) {
print(k);
print(v);
studentTmpList.add(v);
});
print("Final student list");
print(studentTmpList);
studentList = studentTmpList;
setState(() {
});
}).catchError((error) {
print("Failed to load the data");
print(error);
});
}
I've tried adding '!' to force the code to run since I know the data isn't null but no dice. When I try adding the '!' I get a new error stating "The method 'forEach' isn't defined for the type 'Object'".

tronweb : how to get return value using tronweb contract send function

let contract = await window.tronWeb.contract().at(config.contract);
let result = await contract.methods.depositTron()
.send({callValue:amount*1000000})
.then(output=>transaction = output);
console.log("result", result);
I tried to get the result of depositTron method, but returned hash value.
how should I do?
please help me.
Functions invoked by transactions only return value within the EVM (usually when called from another contract).
The hash returned from the send() JS function, is the transaction hash.
You can workaround this by emitting an event log within the contract. Then you can get the value or read emitted logs from the transaction receipt (emitted in JS after the transaction is mined).
Solidity:
contract MyContract {
event Deposit(uint256 indexed amount);
function depositTron() external payable {
emit Deposit(msg.value);
}
}
JS:
contract.methods.depositTron().send({callValue:amount*1000000})
.on('receipt', (receipt) => {
console.log(receipt.logs);
})

FireStore read fails silently and I have no idea why

Help is much appreciated how to trace down this issue, because I am running out of ideas.
I am calling the function getOrderCollection, below, but it aborts after the first line var myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get(); Without trowing anything to the console or jumping into some library when debugging. When I click next statement it jumps back to the calling function.
I am authenticated to the database, companyCollection = FirebaseFirestore.instance.collection('companies') provides an initialized object pointing to the collection and myCompany is a constant with the document id entered by copy/paste.
If some rules for the database but I can't see successful or denied queries with the monitor.
Any ideas how I can proceed tracing down the issue?
Future<void> getOrderCollection() async {
var myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get();
print("companyDoc fetched");
final myDeliveryDocRef = myCompanyDoc.data()['delivery'].toString();
orderCollection = FirebaseFirestore.instance.collection('companies').doc(myCompany).collection('features').doc(myDeliveryDocRef).collection('orders');
orderBriefDoc = FirebaseFirestore.instance.collection('companies').doc(myCompany).collection('features').doc(myDeliveryDocRef);
}
UPDATE: This is collection > document what corresponds to final String myCompany = '4U4kZKXkr3rHA6B04S5K';
As we discussed in your comments, the issue was that you forgot to await the getOrderCollection() function. Even though, as you mentioned, your caller function _deliveryRepository.initRepository() was awaited, you still had to await getOrderCollection() inside your caller method to make sure that the code is waiting for the getOrderCollection() to be executed before it proceeds to the next line.
In general, you want to have some error handling and to type the known types/classes (avoid using var).
Error handling - for async/await place the code inside a try/catch.
Typing - Dart is type safe, which is really great to prevent runtime errors.
Depending on your setup, you might be able to hover over the Firestore.instance.collection(...).doc(...) to see the return type. .doc(...).get() returns a DocumentSnapshot and .collection(...).get() returns a CollectionSnapshot.
Using the above, it should be easier to debug:
Future<void> getOrderCollection() async {
try {
DocumentSnapshot myCompanyDoc = await FirebaseFirestore.instance.collection('companies').doc(myCompany).get();
print("companyDoc fetched");
final myDeliveryDocRef = myCompanyDoc.data()['delivery'].toString();
} catch(e) {
print('Error: ' + e.toString());
}
}
Don't forget to await your other 2 Firestore queries.

How can I catch errors in my firebase function when setting a document fails?

I have a firebase cloud function to create a user document with user data whenever a user registers. How would I return an error when the set() fails? Since this is not an http request (an I don't want to use an http request in this case) I have no response. So how would I catch errors?
export const onUserCreated = functions.region('europe-west1').auth.user().onCreate(async user => {
const privateUserData = {
phoneNumber: user.phoneNumber
}
const publicUserData = {
name: 'Nameless'
}
try
{
await firestore.doc('users').collection('private').doc('data').set(privateUserData);
}catch(error)
{
//What do I put here?
}
try
{
await firestore.doc('users').collection('public').doc('data').set(publicUserData);
}catch(error)
{
//What do I put here?
}
});
You can't "return" an error, since the client doesn't even "know" about this function running, there is nobody to respond to.
You can make a registration collection, and in your function make a document there for the current user (using the uid as the document id). In that document, you can put any information you'd like your user to know (status, errors, etc).
So your clients would have to add a listener to this document to learn about their registration.
In your particular code, I think the error is in doc('users'). I guess you meant doc('users/'+user.uid).
Your catch -block will receive errors that occur on your set -call:
try {
await firestore.doc('users').collection('public').doc('data').set(publicUserData);
} catch (error) {
// here you have the error info.
}

Dart method has errors but does not return error

I am looking at the flutter firebase auth docs.
Specifically, I am looking at these docs, for the method FirebaseAuth.createUserFromEmailAndPassword.
In the docs it lists three errors. But I am confused as to how these errors get communicated back to the caller. It gives no information on the types of these errors. I am really confused here. If it doesn't return an error type, and it doesn't take an error out parameter as an input, how is this method supposed to communicate errors?
Apparently there are three errors just floating in the ether that I can not get a hold of lol.
The method will throw an AuthException. The exception will have a code field. The contents of the code field will explain what went wrong exactly.
ERROR_WEAK_PASSWORD - If the password is not strong enough.
ERROR_INVALID_EMAIL - If the email address is malformed.
ERROR_EMAIL_ALREADY_IN_USE - If the email is already in use by a
different account.
You can handle these errors like any other exception in Dart: with a try/catch.
try {
var result = await FirebaseAuth.createUserFromEmailAndPassword(...);
} catch (e) {
if (e is AuthException) {
switch (e.code) {
case 'ERROR_WEAK_PASSWORD':
// Handle weak password
break;
case 'ERROR_INVALID_EMAIL':
// Handle invalid email
break;
case 'ERROR_EMAIL_ALREADY_IN_USE':
// Handle email in use
break;
}
} else {
// An error other than an AuthException was thrown
}
}