generate custom key with $add angularfire - javascript

How can I generate a custom key in array inside angularfire when I add a new record with the $add function. Just look at when the is the comment below in the source code. This is my code below but still get the random key generated by firebase.
register : function(user){
return simpleLogin.$createUser({
email: user.email,
password: user.password
}).then(function(regUser){
//console.dir(regUser);
var ref = new Firebase(FIREBASE_URL + 'users');
var firebaseUsers = $firebaseArray(ref);
var userInfo = {
date: Firebase.ServerValue.TIMESTAMP,
regUser: regUser.uid,
firstname: user.firstname,
lastname: user.lastname,
email: user.email
}
//this is when i want to generate the key
firebaseUsers.$add(userInfo).then(function(ref) {
});
});
},//register

Calling $add will simply always result in a so-called push id. If you don't want to use those push ids to identify the objects, the solution is to not call $add/push.
Instead you can just access the child that you want to create directly:
var ref = new Firebase(FIREBASE_URL + 'users');
var userInfo = {
date: Firebase.ServerValue.TIMESTAMP,
regUser: regUser.uid,
firstname: user.firstname,
lastname: user.lastname,
email: user.email
}
ref.child(regUser.uid).set(userInfo);
Two things to note here:
the snippet creates the child node under regUser.uid. If you need another key, you can substitute that.
this snippet doesn't use AngularFire, but instead uses the Firebase JavaScript SDK directly. Since AngularFire is built on the JavaScript SDK, they interoperate perfectly. So if you need an operation that isn't immediately obvious in AngularFire, it might be worth it to check whether you can accomplish it (more easily) with the regular Firebase JavaScript SDK.

with the help of mester Frank van Puffelen above I modify the code :
register : function(user){
return simpleLogin.$createUser({
email: user.email,
password: user.password
}).then(function(regUser){
//console.dir(regUser);
var ref = new Firebase(FIREBASE_URL + 'users');
var firebaseUsers = $firebaseArray(ref);
var userInfo = {
date: Firebase.ServerValue.TIMESTAMP,
regUser: regUser.uid,
firstname: user.firstname,
lastname: user.lastname,
email: user.email
}
//the added portion of code
ref.child(regUser.uid).set(userInfo);
firebaseUsers.$add(userInfo).then(function(ref) {
});
});
},//register
and i got the result i want , in angularfire API there is no functions ( 'child()' and set() ) but as mentionned in the post of mester Frank van Puffelen angularfire API is built up on firebase API .
and this is my capture image from my database firebase.

Related

need assistance with firestore in javascript

I want to get the user id on my newly created user so I could name my document to that uid, but it says null.
here's my code
addDriver(){
var $this = this
secondaryApp.auth().createUserWithEmailAndPassword($this.driver.email, $this.driver.password).then(function(user){
$this.$db.collection("driver").doc(user.uid)
.set({
fname: $this.driver.fname,
lname: $this.driver.lname,
contact_number: $this.driver.cnum,
license_number: $this.driver.license,
email: $this.driver.email,
password: $this.driver.password,
})
secondaryApp.auth().signOut();
$this.formHeaderStatus = $this.$db.auth().currentUser
})
},
Also, am I doing this right? coz I'm logged in as an admin? and I want to create a new user without logging myself out.
I am not entirely sure but I believe the problem lies when using the promise returned by createUserWithEmailAndPassword.
From what I have gathered it should be like this :
addDriver(){
var $this = this
secondaryApp.auth().createUserWithEmailAndPassword($this.driver.email, $this.driver.password).then(function(**data**){
$this.$db.collection("driver").doc(**data.user.uid**)
.set({
fname: $this.driver.fname,
lname: $this.driver.lname,
contact_number: $this.driver.cnum,
license_number: $this.driver.license,
email: $this.driver.email,
password: $this.driver.password,
})
secondaryApp.auth().signOut();
$this.formHeaderStatus = $this.$db.auth().currentUser
})
},
Hope it helps, if not, let me know.
But as Franck said, if you want to sign a new user up while staying logged-in, you should use the Admin-SDK in your back end or Cloud Functions

JS library to check if extra data field returned in http response payload?

I’m currently working on building end-to-end testing for an API another team is working on, and I was wondering if anyone perhaps knows about a JS library that I could use to test whether an extra field is returned in HTTP response body? The purpose of this functionality would be to keep the QA team informed when the dev team makes changes to the api via the tests, instead of the developers manually having to let us know they’ve created updates. I know this can be implemented manually but if the wheel already exists, I’d prefer to avoid recreating it lol.
Example scenario:
API call: GET user
- returns : user name, user ID and user birthday.
With proposed functionality, if the dev team made updates to the Get user call, and it returns the following
- return : user name, user ID, user birthday AND user address.
A test would fail to let me know that an extra field that wasn't expected (user address) was returned.
Schema validation seems to be what you are looking for. Besides the library mentioned in another answer, you may also want check a similar one: joi
const Joi = require('joi');
const schema = Joi.object().keys({
userName: Joi.string().alphanum().required(),
userId: Joi.number().required(),
userBirthDay: Joi.number().required(),
})
const result = Joi.validate({
userName: 'johndoe',
userId: 1234567,
userBirthDay: 1970,
userAddress: 'John Doe St.'
}, schema);
if (result.error) {
console.log(result.error.details);
}
In the spec you can make assertion on existence of error key in result object using the assertion library of your choice.
The example above assumes that you are using nodejs as an environment to run tests, but browser version of joi also exists: joi-browser
You need schema validation, there are libraries out there like ajv.
var ajv = new Ajv({ allErrors: true }); // options can be passed, e.g. {allErrors: true}
// API call: GET user - returns : user name, user ID and user birthday.
// With proposed functionality, if the dev team made updates to the Get user call, and it returns the following - return : user name, user ID, user birthday AND user address.
var schema = {
type: "object",
properties: {
userName: {
type: "string",
},
userId: {
type: "string",
},
userBirthdate: {
type: "string",
},
},
required: ["userName", "userId", "userBirthdate"],
additionalProperties: false,
};
var validate = ajv.compile(schema);
var validUser = {
userName: "John",
userId: "john",
userBirthdate: "01012000",
};
var invalidUser = {
userName: "John",
userId: "john",
userBirthdate: "01012000",
userAddress: "World",
};
var valid = validate(validUser);
console.log(`Valid user is valid: ${valid}`);
valid = validate(invalidUser);
console.log(`Invalid user is valid: ${valid}`);
console.log('Validate errors:', validate.errors);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.6.2/ajv.min.js"></script>

Dynamic querying using firebase [duplicate]

This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed 7 years ago.
I have this use case where I have to query based on the parameters sent out by the user in the form of an object. The user could send out multiple parameters to query. It is something similar to what "SELECT * FROM users WHERE FIRST_NAME = 'something' AND LAST_NAME = 'something'" is in SQL.
A sample object could be:
var object= {
email: "some...#google.com",
location: "San Jose, CA"
};
I have these fields (email & location) in my firebase data at some endpoint lets call it /users
So the users endpoint would look like:
{
"randomID1":{
email: "some...#google.com",
location: "San Jose, CA"
},
"randomID2":{
email: "anothe...#fb.com",
location: "Menlo Park, CA"
}
}
I have to use the above mentioned object and generate a query dynamically for firebase, here's what I have:
return $q(function(resolve, reject) {
ref.orderByChild("email");
for(var key in filterObject){
if(filterObject.hasOwnProperty(key)){
console.log("Key: ",key);
console.log("Value: ",filterObject[key]);
ref.equalTo(""+filterObject[key],""+key);
}
}
return ref.on("value", function (snapshot) {
resolve(snapshot.val());
}, function (errorObject) {
reject(errorObject);
});
});
This always returns me all the data and doesn't really filter anything. Can anyone provide suggestions here? I am new to firebase , sorry if this is a naive question.
Thanks
After some attempts, I found an answer.
Basically, Firebase does not allow to query on more than a single property so I query firebase on the first property and if there are any more properties to still query, I use underscore js to filter on those remaining properties.
Code looks like this:
return $q(function(resolve, reject) {
var query = ref ;
for(var key in filterObject){
if(filterObject.hasOwnProperty(key)){
query = query.orderByChild(key);
query = query.equalTo(filterObject[key]);
delete(filterObject[key]);
break; //break out after querying the first property in firebase
}
}
return query.on("value", function (snapshot) {
var objects = snapshot.val();
var result = _.filter(objects, function(obj){
return _.isMatch(obj, filterObject); //for all other objects I use underscorejs to filter
});
resolve(result);
}, function (errorObject) {
reject(errorObject);
});
});

Insert data in collection at Meteor's startup

I would like to insert data at Meteor's startup. (And after from a JSON file)
At startup, I create a new account and I would like to insert data and link it to this account once this one created.
This is the code that creates the new account at startup:
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
}
And after that, I need to insert data and link it to this account with its ID. (In different collections).
So I tried to do something like that, but obviously It didn't work:
UserData = new Mongo.Collection('user_data');
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
UserData.insert({
createdBy: id,
firstname: "test",
/* ... */
});
}
EDIT
Sorry for not have been clear.
The real issue is the :
UserData = new Mongo.Collection('user_data');
declaration is in another file, so I can't do like above.
As it's not in the same file, I tried to get the userId that got "test#test.com" as the email (the account's email created at startup). And once I got it, I want to use it in "createdBy: ID_HERE".
Ok, you'll want to check out Structuring your application. You'll have to make the file with the definition load earlier, or the one with the fixture later.
Normally you have your collections inside lib/ and your fixtures inside server/fixtures.js.
So if you put your insert code into server/fixtures.js it'll work.

Passing mongoose model to ejs and rendering in script tag

I'm returning my model to my view something like this:
User.findOneById('xxx', function(err, result){
res.render('viewName', {user: result});
}
Then, on my view, I have a script block, that I'm trying to assign the user to a variable:
<script id="foundBusiness" type="text/javascript">
var user = <%-user%>
</script>
This renders as follows as the HTML
var user = { __v: 0,
_id: 5315b7b9caaf52e624070002,
firstName: 'Alex',
lastName: 'Brown',
password: '$2a$10$Zs/6JmB3Rq5dddHvjZNUse9vl.8z3hJO.LUGBqMEE.vBMk4lVuav.'}
My issue is around the _id field
This is obviously not valid Javascript, and as such, an error occurs:
SyntaxError: Unexpected token ILLEGAL
What am I doing wrong?
From the horse's mouth
ObjectIds contain the raw MongoDB binary and don't work with templating so we provide the id convenience method to convert them to hexstrings
https://github.com/LearnBoost/mongoose/issues/548
One possible solution -
User.findOneById('xxx', function(err, result){
result._id = result._id.toHexString();
res.render('viewName', {user: result});
}
I think assigning it to result.id would also work.
result._id = result.id;

Categories