extending firebase.database.Reference - firebase

in the old FB I added a helper function to get/set values as follows:
// val() -> get(), resolve with value at ref
// val(value) -> set(value), resolve with value
// val(vals) -> update(vals), resolve with vals
Firebase.prototype.val = function(vals) {
let self=this;
if (!vals) {
return this.once('value').then(
snapshot => {
if (typeof snapshot.val() === 'undefined' || snapshot.val() === null) throw 'INVALID_VALUE';
return snapshot.val();
},
err => {
throw err;
});
}
let singleVal=(vals.constructor != Object); // is singleVal then vals is a single value
if (singleVal ) return this.set(vals); // set single value
if (!singleVal) return this.update(vals).then(() => vals); // update multiple values
};
}
I could then do for example return ref.child(...).val();
This function does not run in V3.
How can I extend firebase in that way in V3 ?
thx!

Here's the solution - I find this extension very handy
// val() -> get(), resolve with value at ref, fails with error.code
// val(value) -> set(value), resolve with value, fails with error.code
// val(vals) -> update(vals), resolve with vals, fails with error.code
firebase.database.Reference.prototype.val = function(vals) {
let path=this.toString().substring(firebase.database().ref().toString().length-1);
let valsAsString = (typeof vals==='string' ? vals : JSON.stringify(vals));
if (!vals) {
return this.once('value').then(
snapshot => {
if (typeof snapshot.val() === 'undefined' || snapshot.val() === null) {
console.log('val('+path+') failed (null) ! '+error.message+' ('+error.code+')');
throw 'INVALID_VALUE';
}
return snapshot.val(); },
error => {
console.log('val('+path+') failed ! '+error.message+' ('+error.code+')');
throw error.code;
});
}
let singleVal=(vals.constructor != Object); // is singleVal then vals is a single value
if (singleVal ) return this.set(vals).then( // set single value
() => {
return vals;
}, error => {
console.log('val('+path+','+valsAsString+') failed ! '+error.message+' ('+error.code+')');
throw error.code;
}
);
return this.update(vals).then( // update multiple values
() => {
return vals;
}, error => {
console.log('val('+path+','+valsAsString+') failed ! '+error.message+' ('+error.code+')');
throw error.code;
}
);
};
}

Related

next.js middleware, NextResponse.redirect() not working when using map or foreach, but it works when using for loops

//this won't work
rules.filter(rule => rule.type === 'redirect' && new RegExp(rule.rule).exec(pathname.slice(1)))
.map(rule => {
console.log('match');
const url = req.nextUrl.clone()
url.pathname = rule.destination
return NextResponse.redirect(url)
})
//this does work
for (let rule of rules) {
const regex: RegExp = new RegExp(rule.rule)
if(regex.exec(pathname.slice(1)) && rule.type === 'redirect') {
console.log('match');
const url = req.nextUrl.clone()
url.pathname = rule.destination
return NextResponse.redirect(url)
}
}
the middleware is already running well with de for loop
Reddit gave me the solution, I leave it here
A return statement inside map simply adds to the map output array.
A return statement in a for loop exits the function.
Next.js will redirect if a middleware returns NextResponse.redirect(), as you would if you used a for loop and return statement.
let result
rules.filter(rule => rule.type === 'redirect' && new RegExp(rule.rule).exec(pathname.slice(1)))
.map(rule => {
console.log('match');
url.pathname = rule.destination
result = NextResponse.redirect(url)
})
return result
Can reproduce this issue. We had to convert:
PRIVATE_ROUTES.forEach((route) => {
if (url.pathname.includes(route)) {
if (!authenticated) {
url.pathname = Routes.auth.signIn;
return NextResponse.redirect(url);
} else if (
req.cookies.get('auth-next-url') &&
url.pathname !== req.cookies.get('auth-next-url')
) {
url.pathname = req.cookies.get('auth-next-url')!;
return NextResponse.redirect(url);
}
}
});
To this:
for (let route of PRIVATE_ROUTES) {
if (url.pathname.includes(route)) {
if (!authenticated) {
url.pathname = Routes.auth.signIn;
return NextResponse.redirect(url);
} else if (
req.cookies.get('auth-next-url') &&
url.pathname !== req.cookies.get('auth-next-url')
) {
url.pathname = req.cookies.get('auth-next-url')!;
return NextResponse.redirect(url);
}
}
}

alexa sdk: can't get persitentAttributes

i'm trying to add persistent attributes to my lambda function.
i created a dynamoDB table and added it to the triggers of my lambda function.
i copied a sample code from github, but when i try to launch the skill i get an error. The console log shows:
{
"errorMessage": "Could not read item (amzn1.ask.account.AGIIYNRXWDLBD6XEPW72QS2BHGXNP7NWYBEWSH2XLSXZP64X3NCYEMVK233VFDWH77ZB6DAK6YJ53SZLNUFVQ56CYOVCILS7QFZI4CIRDWC3PAHS4QG27YUY5PTT6QEIK46YFNTJT54YAKNGOWV2UO66XZACFDQ5SEXKJYOBNFNIZNUXKNTIAAYZG4R5ZU4FMLPDZZN64KLINNA) from table (Spiele): The provided key element does not match the schema",
"errorType": "AskSdk.DynamoDbPersistenceAdapter Error",
"stackTrace": [
"Object.createAskSdkError (/var/task/node_modules/ask-sdk-dynamodb-persistence-adapter/lib/utils/AskSdkUtils.js:22:17)",
"DynamoDbPersistenceAdapter.<anonymous> (/var/task/node_modules/ask-sdk-dynamodb-persistence-adapter/lib/attributes/persistence/DynamoDbPersistenceAdapter.js:123:49)",
"step (/var/task/node_modules/ask-sdk-dynamodb-persistence-adapter/lib/attributes/persistence/DynamoDbPersistenceAdapter.js:44:23)",
"Object.throw (/var/task/node_modules/ask-sdk-dynamodb-persistence-adapter/lib/attributes/persistence/DynamoDbPersistenceAdapter.js:25:53)",
"rejected (/var/task/node_modules/ask-sdk-dynamodb-persistence-adapter/lib/attributes/persistence/DynamoDbPersistenceAdapter.js:17:65)",
"<anonymous>",
"process._tickDomainCallback (internal/process/next_tick.js:228:7)"
]
}
the table contains a primary key "name" and sort key "UserId". is that wrong?
here is my index.js:
const Alexa = require('ask-sdk');
// Define the skill features
let skill;
/**
* If this is the first start of the skill, grab the user's data from Dynamo and
* set the session attributes to the persistent data.
*/
const GetUserDataInterceptor = {
process(handlerInput) {
let attributes = handlerInput.attributesManager.getSessionAttributes();
if (handlerInput.requestEnvelope.request.type === 'LaunchRequest' && !attributes['isInitialized']) {
return new Promise((resolve, reject) => {
handlerInput.attributesManager.getPersistentAttributes()
.then((attributes) => {
attributes['isInitialized'] = true;
saveUser(handlerInput, attributes, 'session');
resolve();
})
.catch((error) => {
reject(error);
})
});
}
}
};
function saveUser(handlerInput, attributes, mode) {
if(mode === 'session'){
handlerInput.attributesManager.setSessionAttributes(attributes);
} else if(mode === 'persistent') {
console.info("Saving to Dynamo: ",attributes);
return new Promise((resolve, reject) => {
handlerInput.attributesManager.getPersistentAttributes()
.then((persistent) => {
delete attributes['isInitialized'];
handlerInput.attributesManager.setPersistentAttributes(attributes);
resolve(handlerInput.attributesManager.savePersistentAttributes());
})
.catch((error) => {
reject(error);
});
});
}
}
const LaunchHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
console.info("LaunchRequest");
let attributes = handlerInput.attributesManager.getSessionAttributes();
console.info("Test the load: " + attributes['isInitialized']);
attributes['FOO'] = "BAR";
saveUser(handlerInput, attributes, 'persistent');
return handlerInput.responseBuilder
.speak('Hello')
.reprompt('Hello')
.getResponse();
}
}
exports.handler = Alexa.SkillBuilders.standard()
.addRequestHandlers(
LaunchHandler
)
.addRequestInterceptors(GetUserDataInterceptor)
.withTableName('Spiele')
.withAutoCreateTable(true)
.withDynamoDbClient()
.lambda();
can anyone tell me what i'm doing wrong?
please confirm the partition key is 'userId' not 'UserId' (notice the uppercase U).
Also I would suggest using 'this' object.
Let me know if that helps.
Cheers
Below code is for python lambda function
from ask_sdk_core.skill_builder import CustomSkillBuilder
from ask_sdk_dynamodb.adapter import DynamoDbAdapter
sb = SkillBuilder()
sb = CustomSkillBuilder(persistence_adapter = dynamodb_adapter)

AngularFire2 Firebase Observable never ends (list is empty)

I'm trying to query an empty firebase list. The problem is that the observable method subscribe never finish and I can't show to user that ddbb list is empty.
The function getUserAppointmentsByDate(...) is calling getUserAppointments(...), where this.database.list('/appointment/users/' + user_uid) is an empty firebase list for the input user (user_uid).
how should I manage an empty query to firebase?
thanks in advance!
getUserAppointmentsByDate(user_uid: string, start: string, end: string) {
if (typeof (user_uid) == "undefined" || typeof (start) == "undefined" || typeof (end) == "undefined") {
console.error("invalid argument for getPatientReport");
return;
}
return this.getUserAppointments(user_uid)
.map(
(appointment) => {
return appointment
.filter((appointment) => {
var appointmentStart = new Date(appointment.start);
var startFilter = new Date(start);
var endFilter = new Date(end);
//Filter old, not cancelled and not deleted
return (appointmentStart.getTime() < endFilter.getTime())
&& (appointmentStart.getTime() > startFilter.getTime())
&& (appointment.status != AppointmentStatus.CANCELLED);
});
})
}
getUserAppointments(user_uid: string): any {
return this.database.list('/appointment/users/' + user_uid) //*THIS IS AN EMPTY LIST
.mergeMap((appointments) => {
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})
}
As the this.database.list('/appointment/users/' + user_uid) return a empty array. Observable.forkJoin(appointments.map( complete without emit any value (that is the expected way of forkJoin works). In this case, you have two options, handling in the complete function.
.subscribe(
res => console.log('I got values'),
err => console.log('I got errors'),
// do it whatever you want here
() => console.log('I complete with any values')
)
or handle in an if statement:
import { of } from 'rxjs/observable/of';
...
return this.database.list('/appointment/users/' + user_uid)
.mergeMap((appointments) => {
if (appointments.length === 0) return of([]);
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})

fetchProvidersForEmail returning undefined

I'm trying to check if an email exists by using fetchProvidersForEmail, however the function that I've written keeps returning undefined.
var emailExists = (emailAddress) => {
firebase.auth().fetchProvidersForEmail(emailAddress)
.then((providers) => {
return providers.length > 0;
});
};
In addition to this, I have also tried
var emailExists = (emailAddress) => {
var exists = false;
firebase.auth().fetchProvidersForEmail(emailAddress)
.then((providers) => {
exists = providers.length > 0;
});
return exists;
};
When replacing return ... with console.log(providers.length > 0) the value that I expect is returned. What am I doing wrong here?
You have to do this:
var emailExists = (emailAddress) => {
return firebase.auth().fetchProvidersForEmail(emailAddress)
.then((providers) => {
return providers.length > 0;
}); };
firebase.auth().fetchProvidersForEmail returns a promise with the boolean of whether providers.length > 0 or not.
But in your emailExists function, you didn't return the promise. So undefined is returned.

Issue with observable fork join

Hi I have 3 tables of which, each one is child of another. I wrote a method to fetch from sqllite db as follows
public downloadFromOfflineDB(db,testSO){
var observableBatch = [];
observableBatch.push(db.executeSql("select * from TMP_AUD WHERE CRE_BY=? AND AUD_NUMBER=? ",
[localStorage.getItem("user_name"), testSO.auditNumber]).then(
response => {
this._util.logData('In downloadPendingInstancesForSyncFromOfflineDB- folder'+response.rows.length+'ID= '+response.rows.item(0).FLD_NUMBER);
if (response && response.rows && response.rows.length > 0) {
if (response && response.rows && response.rows.length > 0) {
var FLD_NUMBER = response.rows.item(0).FLD_NUMBER;
var folderArray = []
observableBatch.push(db.executeSql("select * from TMP_FOLDER WHERE CRE_BY=? AND FLD_NUMBER=? ",
[localStorage.getItem("user_name"), FLD_NUMBER]).then(
a => {
this._util.logData('In downloadPendingInstancesForSyncFromOfflineDB-TMP_FOLDER'+a.rows.length);
if (a && a.rows && a.rows.length > 0) {
for (let i = 0; i < a.rows.length; i++) {
var folderObj = {
folderName: a.rows.item(i).FLD_NAME,
files:[]
}
var FLD_NAME = a.rows.item(i).FLD_NAME
this._util.logData('In downloadPendingInstancesForSyncFromOfflineDB-TMP_FOLDER '+FLD_NAME);
observableBatch.push( db.executeSql("select * from TMP_FILES WHERE CRE_BY=? AND FLD_NAME=? ",
[localStorage.getItem("user_name"), FLD_NAME]).then(
b => {
this._util.logData('In downloadPendingInstancesForSyncFromOfflineDB-TMP_FILES'+b.rows.length);
var fileArray = [];
if (b && b.rows && b.rows.length > 0) {
for (let j = 0; j < b.rows.length; j++) {
var fileSO = {
compliance: b.rows.item(j).COMPLIANCE,
remarks: b.rows.item(j).REMARKS,
fileName: b.rows.item(j).FILE_NAME,
title: b.rows.item(j).TITLE
}
);
fileArray.push(fileSO);
}}
folderObj.files=fileArray;
}).catch(
e => {
this._util.logData('For sync error'+JSON.stringify(e));
return Observable.throw("An error occurred during sync");
})
);
folderArray.push(folderObj);
}}
}).catch(
e => {
this._util.logData('For sync error'+JSON.stringify(e));
return Observable.throw("An error occurred during sync");
})
);
}
}
testSO.folderArray = folderArray;
this._util.logData('Candidate for selected for sync' + JSON.stringify(testSO));
})
);
return Observable.forkJoin(observableBatch);
}
The issue here is below method is not waiting for all the calls to finish
public getFiles(testSO) {
return Observable.create(observer => {
this.platform.ready().then(() => {
this.sqlite.create({
name: 'offline.db',
location: 'default'
}).then((db: SQLiteObject) => {
this.downloadFromOfflineDB(db, testSO).subscribe(c => {
observer.next(c[0]);//This is undefined
observer.complete();
},
error => {
observer.error("An error occurred sync files.");
});
});
});
});
}
First method is executing, while second method returns before first execution is complete and I am not getting my object testSO populated. Can someone please guide me and tel me what I am doing wrong here.I used observable fork Join.
Looks like you are calling Observable.forkJoin(observableBatch) with only one item - result of db.executeSql. When you add more items later on it doesn't affect forkJoin.

Resources