This started to happen after I updated from 5.0.0 to 5.2.1, but it also happens on 5.1.0, before it was enough with:
if (task.Result.Exist){}
But now I have to do:
if (task.Result != null && task.Result.Exist){}
because somehow task.Result may be null, is that okay?
I tested with this piece of code:
DatabaseRoot.Child("users").Child(userId).GetValueAsync().ContinueWith((task) =>
{
if (task.IsFaulted)
{
Debug.LogError("Firebase task error: " + task.Exception.Message);
}
else if (task.IsCompleted)
{
Debug.Log("Task completed.");
try
{
Debug.Log("Result " + (task.Result == null));
Debug.Log("Result " + task.Result.Exists);
Debug.Log("Result " + task.Result.Value);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
});
It works well (as it used to be) if I return to the 5.0.0, but I need some of the patches in the newer versions.
Related
I started to learn ES6 and I'm transforming my project from ES5 to ES6. I want to ask if it's sense to use async/await in middlewares ? How to use it in this example :
middlewareObj.checkCampground = (req,res,next) =>{
if(req.isAuthenticated()){
Campground.findById(req.params.id, (err, foundCampground) =>{
if(err || !foundCampground){
req.flash("error", "Campground not found");
res.redirect("back");
} else {
if(foundCampground.author.id.equals(req.user._id) || req.user.isAdmin){
next();
} else {
req.flash("error", "You don't have permission to do that");
res.redirect("back");
}
}
});
} else {
req.flash("error", "You need to be logged in to do that");
res.redirect("back");
}
};
When you only have a single asynchronous operation like you do here, you don't gain much (if anything) from switching to await. The bigger benefits come when you need to sequence multiple asynchronous operations and perhaps even have some branching. Then await lets you write much simpler code.
Plus, most of your code here is really just about checking results and getting the right error message back to the user and that doesn't get a lot simpler with await as it's just a bunch of rote checks either way.
Here's an implementation that also attempts to use exceptions to consolidate all the error returns so you don't have as many places where you're doing req.flash() and res.redirect():
middlewareObj.checkCampground = async (req,res,next) => {
try {
if(req.isAuthenticated()) {
throw new Error("You need to be logged in to do that");
}
const foundCampground = await Campground.findById(req.params.id);
if (!foundCampground) {
throw new Error("Campgound not found")
}
if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
throw new Error("You don't have permission to do that");
}
} catch(e) {
console.log(e);
req.flash(e.message);
res.redirect("back");
}
};
Here's another alternative without async/await that just attempts to consolidate the error handling a bit. You can't get around the fact that there are three if checks and four possible errors:
middlewareObj.checkCampground = (req,res,next) => {
function error(msg, location = "back") {
req.flash(msg);
res.redirect(location);
}
if(req.isAuthenticated()) {
error("You need to be logged in to do that");
return;
}
Campground.findById(req.params.id).then(foundCampground => {
if (!foundCampground) {
error("Campground not found");
} else if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
error("You don't have permission to do that");
}
}).catch(err => {
console.log(err);
error("Database Error - Campground not found");
});
};
Note that in both of these, I make sure and log an actual database error if there is one.
Okay. I've been using Flutter for a little more than a year now. I've been using this same code in almost every app, and it works. For some reason, it doesn't work in this new app that I'm building.
String testString(DocumentSnapshot doc, String val) {
try {
if (doc == null) {
return "error! DB not found!";
}
if (doc[val] == null) {
return "'" + val + "' doesn't exist in DB";
}
return doc[val];
} catch (e) {
return "Error: something went wrong";
}
}
I've also tried this:
String testUndString(DocumentSnapshot doc, String val) {
try {
return doc != null ? (doc[val] != null ? doc[val] : "undefined") : "undefined";
} catch (e) {
return "Error: something went wrong";
}
}
and this:
String testUndString(DocumentSnapshot doc, String val) {
try {
return doc.data != null ? (doc[val] != null ? doc[val] : "undefined") : "undefined";
} catch (e) {
return "Error: something went wrong";
}
}
After doing some searching, it looks like I've done this correctly, but it still returns the error:
NoSuchMethodError (NoSuchMethodError: The method '[]' was called on null.)
Try this code:
if (doc is !DocumentSnapshot) {
return "error! DB not found!";
}
I have a Xamarin.Forms application, which uses Xamarin.Essentials and Plugin.Permissions plugin.
permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
In UWP, It throws an Exception
"Server execution failed".
Any ideas what can cause it, and how this can be solved?
According to your code, I guess that you want to request and check location permission, if yes, you can take a look the following code to request location permission.
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await DisplayAlert("Need location", "Gunna need that location", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
status = results[Permission.Location];
}
if (status == PermissionStatus.Granted)
{
var results = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromSeconds(10));
LabelGeolocation.Text = "Lat: " + results.Latitude + " Long: " + results.Longitude;
}
else if(status != PermissionStatus.Unknown)
{
await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
}
}
catch (Exception ex)
{
LabelGeolocation.Text = "Error: " + ex;
}
Please check Location in package.appxmanifest before.
I have a question, it is possible that it can be called again method that was executed in a handlerIntent? When you come back and finish talking? I need to rerun:
const response = await logic.consultaService (1,1,1100);
after finishing the call
Without the user having to say the command again
I require an automatic action until the user says stop
return handlerInput.responseBuilder
.speak (speechText)
.reprompt ('tss')
.getResponse ();
thank you.
Code:
const CustomServiceIntent = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'CustomServiceIntent';
},
async handle(handlerInput) {
try {
await logic.callDirectiveService(handlerInput,"espera");
} catch (error) {
console.log("Progressive error : " + error);
}
const response = await logic.consultaServicio(1,1,1100);
let speechText="";
if(response) {
const results = response;
results.forEach(function (elemento, indice, array) {
speechText += " El " + " " + " siguiente " +" "+ " niƱo " + " "+ " en "+" " + " salir es " + " " +" . " + elemento.nombre + " . " ;
});
}
return handlerInput.responseBuilder
.speak(speechText)
.reprompt('tss')
.getResponse();
}
};
may I suggest you use Dialog Management to solve this?, if the idea is that the user says "stop" or something you can do that with Dialog Management handling the status. Give it a thought I think that might work. Seems to me that what you want to achieve can be realized using that Dialog Management feature.
I hope it helps otherwise lets give it a thought.
I have the cloud function like so:
exports.updateNewsCount = functions.database.ref('/channels/{channelId}/news/{newsId}/')
.onWrite (event => {
const channelId = event.params.channelId;
const newsId = event.params.newsId;
let CntRef = admin.database().ref('/channelDetails/' + channelId + '/newsCnt');
if (event.data.exists() && !event.data.previous.exists()){
return CntRef.transaction(function(current){
if (current){
console.log ('current is not null');
return (current || 0) + 1;
}
else {
console.log('current is null');
return current;
}
},function(error, b, d){
if (error)
console.log(error);
else
console.log ('error is null');
if (b)
console.log('boolean is true');
else
console.log('boolean is false');
if (d)
console.log('snapshot is ' + d);
else
console.log ('snapshot is null');
}).then(()=>{});
} else if (!event.data.exists() && event.data.previous.exists()){
return CntRef.transaction(function(current){
if (current)
return (current || 1) - 1;
else
return current;
}, function(error, b, d){if (error) console.log(error); if (d) console.log(d);}).then(()=>{});
}
});
It fires consistently as I can see the log entries. However, the newsCnt field is not updated as expected. Sometimes it gets updated and sometimes not!!! What am I doing wrong here?
You should expect that a transaction be called potentially multiple times, the first time with null. That's the way transactions work. Please read the documentation here.
In particular note the following callout in that section:
Note: Because your update function is called multiple times, it must
be able to handle null data. Even if there is existing data in your
remote database, it may not be locally cached when the transaction
function is run, resulting in null for the initial value.