postman scripting with static guids - javascript

I'm hoping to use Postman to generate and insert test data for an API project I'm working on. The resources in the API have foreign key constraints, so I want to be able to generate static guids for the resources, and share those IDs among all the other requests so that we can maintain the references and have valid foreign keys.
At the moment I'm generating data that I want to keep accessible to all the requests in the collection in a pre-request script at the collection level:
// set the user ID for our test user
var userId = pm.variables.replaceIn("{{$guid}}");
pm.collectionVariables.set("userId", userId);
// then generate a product ID
var productId = pm.variables.replaceIn("{{$guid}}");
pm.collectionVariables.set("productId", productId);
// create a few vendors
var vendorId1 = pm.variables.replaceIn("{{$guid}}");
pm.collectionVariables.set("vendorId1", vendorId1);
var vendorId2 = pm.variables.replaceIn("{{$guid}}");
pm.collectionVariables.set("vendorId1", vendorId1);
// etc
My thought was that I'd use the userId in all subsequent POSTs so there'd be a real user to associate a new object with, then use the vendor IDs with the product inserts, etc.
However, the pre-request script runs before each request-- I think it's re-creating all these values rather than keeping them static, so my plan to maintain integrity isn't working.
Is there a better strategy? For example, can I capture the ID of the inserted object from the request response and pass that variable on to the next request in the workflow so that it can use that ID for the associated resources?

You could test if the userId is already set, and only if it isn't set your variables, something like:
if (!pm.collectionVariables.get("userId")) {
// set the user ID for our test user
var userId = pm.variables.replaceIn("{{$guid}}");
pm.collectionVariables.set("userId", userId);
// set your other variables...
}

Related

How can I access a specific attribute of a specific document in a mongoDB collection?

To summarize, I am working with 2 collections - 'usercollection' and 'groupcollection' and I would like to associate users with groups. I don't want to have 2 copies of all the user documents so I have a unique ID attribute for each user that I want to use to associate specific users with specific groups. This is all running on a localhost webserver so I'm getting the input from an html page with a form in it where you enter 'username' and 'groupname'. I tried using the .distinct() function with query as 'username' and the target field/attribute as 'uid'.
// Set our internal DB variable
var db = req.db;
// Get our form values. These rely on the "name" attributes
var userName = req.body.username;
// Set query and options for searching usercollection
var query = {"username" : userName};
const fieldName = "uid";
// Set our collections
var users = db.get('usercollection');
// Get UID corresponding to username
var uidToAdd = users.distinct(fieldName, query);
This is what I attempted (with some other lines that aren't relevant taken out) but it just returned a null object so I'm at a bit of a loss. Also, I'm still a beginner with nodejs/javascript/mongoDB so the more informative the answer the better! When I do the same code in the mongo shell I can get the actual value of the 'uid' attribute so I really don't know what's going wrong
I am not sure I am following you. But if I understood correctly, if you want to make a relationship between 'usercollection' and 'groupcolletion', you can simply create those 2 collections and each user in 'usercollection' should have a field with 'groupid' as a reference. In this way, you can access 'groupcollection' easily.
Here is an example with using mongoose.
In User model
...
groupId: {
type: mongoose.Schema.Types.ObjectID
ref: "Group"
}
...
Later you can also use 'populate' to fetch 'Group' information.
...
let data = await User.findById(id).populate('groupId');
...

Firestore query with only a field inside an array

This is the thing I want to accomplish: I'm building a web shop. The web shop has a React Front-end. The front-end fetches 5 collections from Firestore and displays all the items from the collection array on the shop page. A user selects an item on the shop page. I send the item fields such as (price, name, quantity, id) to my express server and the server makes a checkout session of the item fields. The user goes to a Stripe checkout form and is sent back to my front-end by Stripe when the payment is complete. I listen for that event on my server and when then want to update the quantity field of the item in Firestore.
But how do I query Firestore for this item? Is there a way to query Firestore with only this id field (or name field)? Some something like:
db
.collection('collections')
.where('id', '===', 1)
Or do I need to save the document id (of the collection) as a field inside the item map and also send that to Stripe? Or is there a better way to do this? I can't find anything online about this.
Here is a screenshot of Firestore.
Please forgive my beginner question. I'm still learning React, Firestore and Node.js.
First be sure you are sticking to the Firestore terminology correctly. There are collections and there are documents.
Collections you access via a path such as:
collRef = db.collection("products")
collRef = db.collection("products").where("quanity_on_hand", ">", "0")
collRef = db.collection("products").doc("12345").collection("purchase_history")
The latter instance can also be accessed via collRef = db.collection("products/12345/purchase_history").
In all the above cases you will get back a CollectionReference.
Documents you access such as:
docRef = db.collection("products").doc("12345")
docRef = db.doc("products/12345")
This returns you a DocumentReference for the document whose ID is "12345" in the collection "products".
So for your code example above, you want to use docRef = db.doc("collections/1") to get back the DocumentReference for the item you are after. (Or, alternatively, you could use: docRef = db.collection("collections").doc("1")
If you stick with the code that you have above, you'd get back a CollectionReference then you'd need to fetch the data with .get(), then extract the resulting documents (that will just be a single document), then work with that. Oh...and you will need to put an "id" field into all of your documents because the document's ID value (the "name" of the document) is not part of the document by default so if you want to use .where("id", "==", "1"), then you need to add an "id" field to your document and populate it correctly.
If you go with docRef = db.doc("collections/1"), you are querying for the document directly and will get back a reference to just that one. No need for extra fields, nor extracting a single document from a result set.

Need helping retrieving data from Firebase

So I've been using Firebase as a database for my website (this is a web based project, using HTML, CSS and JS) and I'm running into a problem retrieving data from it.
Basically this site allows users to create a profile for a character (they can fill in the name, the characters stats etc...) and when they click submit, it'll save the values they filled out to the database.
The values are saved perfectly fine, but when I go to retrieve the data the command doesn't seem to do anything.
So in order to get the profiles, I've been trying to use this bit of code to get whatever is stored at the specified .ref(path):
var uid = firebase.auth().currentUser.uid;
var getChar = firebase.database().ref('/users/' + uid + '/chars/').orderByKey();
Which according to the Firebase docs should return a list of keys at the path that I specified in .ref(). However whenever I try to access whatever is in the var, it just gives me the string that contains a link to the database that looks like this:
https://#mydatabaseurlhere.firebaseio.com/users/uid/chars
Where #mydatabaseurlhere is the url I created on the Firebase app, and the uid is the authenticated user's ID.
I've been reading the docs, and its telling me that the above code should return a list of whatever is at the path that I specified, but so far it just gives me a link. Is there something I've been missing from the Docs that'll allow me to access whatever data is currently in the database? Because I've tried to take a snapshot using .once() to no avail either. I've also set the rules on /users/ to allow anyone to read/write to the database but I'm still not able to access the data (or maybe I am accessing, I'm just missing how to retrieve it).
Either way, I'm wondering how one can go about accessing this data, as I'm extremely confused as to why I can't seem to retrieve the data that has been successfully written to the database.
You're defining a query. But that doesn't yet retrieve the data.
To retrieve the data, you need to attach a listener. For example:
var uid = firebase.auth().currentUser.uid;
var getChar = firebase.database().ref('/users/' + uid + '/chars/').orderByKey();
getChar.on('value', function(snapshot) {
snapshot.forEach(function(child) {
console.log(child.key, child.val());
});
});

Meteor: Turning email address into MD5hash on server, and accessing on client

So I want to use Gravatar avatars on my website. I got the appropriate packages for it. The way it works, it turns email addresses into an "MD5Hash." That's sent to Gravatar in exchange for the image url.
Fine, but I want to display avatars without exposing everyone's email address. At the same time, I have users already that likely already have gravatars, and I think it would be cool if their avatars just popped up one day, without adding another field to the user profiles collection, or asking them to.
Is there a way to do some of this on the server and accomplish my goal?
Handlebars.registerHelper("gravatar", function(id){
var email = Meteor.users.findOne({_id: id}).emails[0].address;
var options = {
secure: true,
size: 29,
default: 'retro'
};
var md5Hash = Gravatar.hash(email);
// 5658ffccee7f0ebfda2b226238b1eb6e
var url = Gravatar.imageUrl(md5Hash, options);
// https://secure.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e
return url;
});
Hackish:
On the server:
userArray = Meteor.users.find(query,{fields: {"emails.address": 1}}).fetch();
userArray.forEach(function(el,i,a){
a[i] = { _id: el._id, md5hash: Gravatar.hash(el.emails[0].address) };
}
where query is whatever your criteria are, will get you an array of objects whose _id matches the _id of each user and whose md5hash value is the hash of that user's email. You can set up a method to return this array to you when you need it.
The good news is that your client can use these hashes to get avatars in whatever sizes might be necessary at any time.
Much less hackish:
The problem with the above is that your server is frequently going to be recomputing the md5hash of each email. Plus you're getting a potentially big and non-reactive array from the server. You'll live to regret this. You really just want to add an md5hash key to the emails array in the user document, initialize it for existing users, and make sure that new users always have this key set at creation time. This will let you handle either single-email address users or multiple-email address users.

Double indexing in associative array

I'm building a server using Node.js. I store the objects representing my users in an associative array and right now the index of those objects are the sockets id of that connection. Using the Socket.io library i obtain it by simply doing socket.id, so for each handler that takes care of my requests I can always know which user made the request.
Client-side every user has the ids of the connected users (that are different from the socket ids).
The problem araises when i have an handler that is used to send a message from an user to another, i make an example:
User A needs to send a message to user B, my protocol specifies the message as something like this:
MSG_KEY:{MSG:'hello world',USER_ID:'12345'}
Server-side i have an handler that listens to "MSG_KEY" and when the message is sent it is executed and using the socket.id I can retrieve who made the request, but the problem is that i need to get also the user B but this time using his USER_ID. I don't want to use the socket.id to avoid session spoofing.
I first thought about indexing in my array the users by indexing them both from socket.id and user id.
My question is: is it a good idea to do this? Does socket.io provide a way to simplify this?
There's no particular reason you can't do that. I would use two separate objects (maps), and probably have the users be represented by objects rather than strings so that there was really only one user (referenced from two places).
E.g., a user:
var user = {userid: "JohnD", name: "John Doe"};
and then:
var usersByID = {};
usersByName[user.userid];
and
var usersBySocket = {};
usersBySocket[theSocketID] = user;
Or even
var users = {
byID: {},
bySocket: {}
};
users.byID[user.userid] = user;
users.bySocket[theSocketID] = user;

Categories