Auth0: fetch data of group of users - javascript

I have an application with Auth0 and graphQl.
I use dataloaders to batching requests to DB. https://github.com/graphql/dataloader
For example, fetching data from DB looks like:
// Booking is Mongoose model
new DataLoader(
bookingIds => Booking.find({ _id: { $in: bookingIds } }),
);
And now I need to fetch data about group of users. Of course, I can write
// getUser is ManagementClient.getUser from 'auth0' package
new DataLoader(
userIds => Promise.all(
userIds.map(
id => getUser({ id }),
),
),
)
This solution is slowly. Can I get data of collection of users by one request?

I work with the Auth0 Community team. You can retrieve users with the GET users endpoint from the management console. Give it a look when you get a chance. Thanks!

Related

How do I fetch user information to display in a feed of posts using firebase storage solutions?

I'm building a forum-style application where users post content that displays on a global feed. I want to display information about the user in posts (photoURL, displayName) similar to Twitter.
I have firebase v9 using the authentication and firestore for the posts. The reason I want to reference the auth is that I can catch changes to the user's information as it happens, this way the feed is up to date.
I save the user's unique ID with the post so I am able to reference who to display. I can successfully reference the post title and description with doc.title & doc.description however I get stuck when retrieving user information. I'm trying doc.UserID.displayName for the display name but I know this is incorrect. I can't find anything in the docs for this specific use case, is this something that I can do with just firestore and auth?
Do I need to create a reference to the auth storage with doc.UserID?
Here is the code:
// add a new post
addPostForm.addEventListener('submit', (e) => {
e.preventDefault();
onAuthStateChanged(auth, (user) => {
const colRef = collection(db, 'Posts');
console.log(hiddenURL.value);
addDoc(colRef, {
UserID: user.uid,
beatURL: hiddenURL.value,
title: addPostForm.postTitle.value,
description: addPostForm.postDescription.value,
})
.then(() => {
console.log("Document written with ID: ", doc.id);
addPostModal.classList.remove('open');
addPostForm.querySelector('.error').textContent = "";
})
.catch(error => {
addPostForm.querySelector('.error').textContent = error.message;
alert(error);
})
})
});
export const initApp = async () => {
initFirebaseAuth;
const posts = await collection(db, 'Posts');
// render data to the page
return renderPosts(posts);
};
const renderPosts = (posts) => {
const main = document.getElementById("feed");
onSnapshot(posts, (snapshot) => {
let cardsArray = []
snapshot.docs.forEach((doc, user) => {
cardsArray.push({ ...doc.data(), id: doc.id })
name.textContent = `${doc.UserID.displayName}`; // users display name
avatar.src = doc.UserID.photoURL; //user's image
description.textContent = `${post.description}`;
title.textContent = `${post.title}`;
});
console.log(cardsArray);
});
};
There are two cases and approaches at first sight:
1. Your users profiles are only available in the Auth Service
In this case, via the JS SDK, a user X cannot "query" the Auth profile of a user Y.
This means that you need to save the author's displayName together with the author uid when the post is created.
2. Your users profiles are also available in a users collection (a common pattern)
In this case, when you display a post, you could fetch the user's document to get the author's displayName.
However, in the NoSQL world, you should not be afraid to duplicate data and denormalize your data model. When designing your data-model you should think about it from a query perspective, trying to minimize the number of queries for a given screen/use case. So approach #1 is recommended, even if you maintain a user's collection.
In case of changes in the user's profile, in order to synchronyse the post documents and user's data a common approach is to use a set of Cloud Functions (which are executed in the back-end) to update the post documents. The link between the posts and the users profile being the user's uid.

What's the proper way to use RTK Query when dealing with multiple base URLS?

I have migrated towards RTK and enjoying it immensely so far, but one thing I got stuck on is the following situation:
We have (for keeping it simple's sake) two endpoints:
www.domain-customer.com <- fetching customer data
www.domain-order.com <- can mutate some user data here
And the website itself is hosted on another domain.
I need to fetch data from the customer endpoint, but in order to update certain things I need to make a mutation to the order endpoint. At first I thought I should define a createApi per base URL, but then I'm pretty sure I can't have the invalidation. I would like to have this previous mutation invalidate the data for the customer, so that the new data gets refetched.
So this is what I have come up with, but I'd like some input on if this is the way to move forward.
export const customerApi = createApi({
reducerPath: "/../",
baseQuery: fetchBaseQuery({ baseUrl: "https://www.domain-customer.com/" }),
endpoints: (builder) => ({
// write provides tag stuff here
getCustomerExample: builder.query({ query: (name) => `customer/${name}` }),
// please ignore the details of the mutation, I haven't practiced much with it yet.
updateCustomer: builder.mutation({
queryFn: async (name) => {
const response = await fetch(
`https://www.domain-order.com/updateCustomer`,
{update mutation stuff here}
);
const data = await response.json();
return { data };
}
// write invalidate stuff here
})
})
});
Is this the way to go about it? Or should there even be a giant createAPI that will hold all the mutations and queries?
Generally, yes, you should have one single createApi if data is connected enough that you want to invalidate them.
Note that while most examples just show queries to something under baseQuery, you can also just have a url parameter (or string) returned from query that contains a full domain -fetchBaseQuery 100% supports that use case.
So in your case:
updateCustomer: builder.mutation({
query: (name) => ({
url: `https://www.domain-order.com/updateCustomer`,
// update mutation stuff here
})
// write invalidate stuff here
})

Connect clients to differents DBs on MeteorJS

Recently I have a requirement to be able to implement a MeteorJS application capable of connecting to different databases according to the connected user.
The structure of the database is the same, only the information it contains changes
I tried connecting through DDP to another backend connected to the necessary database and also by using MongoInternals but, although the users log in correctly, the other collections continue to consult the database by default.
In the server code
const connection = DDP.connect(url)
Accounts.connection = Meteor.connection = connection
_.each(
[
"subscribe",
"methods",
"call",
"apply",
"status",
"reconnect",
"disconnect",
],
function (name) {
Meteor[name] = _.bind(Meteor.connection[name], Meteor.connection); // 55
}
);
ConfigApps = new Mongo.Collection("configapps")
Here the ConfigApps collection obtains the correct data from the database but from the Frontend the data from the other database is read
Or:
var database = new MongoInternals.RemoteCollectionDriver(
"mongodb://localhost:27017/spence-local"
);
ConfigApps = new Mongo.Collection("configapps", {
_driver: database,
_suppressSameNameError: true,
});
Meteor.users = new Mongo.Collection("users", {
_driver: database,
_suppressSameNameError: true,
});
With the same results. User can connect but only one database is read for all querys in the application
Some information or clue would be great.

Firebase Database - Login

I have a register page working well, this is my database.
enter image description here
Each one has an ID and you Login using Username and password,
And I am using this code, to verify if the username is in database.
ref.child("accounts").orderByChild("lowerun").equalTo(username.toLowerCase()).once("value",snapshot => {
if (snapshot.exists()){
const userData = snapshot.val();
console.log(userData)
}
})
But how do I get the password for the username?
Dudis! Welcome to SO! It looks like you're using Firebase Realtime Database? I think you're using the database API incorrectly if you're trying to fetch user number 1 in your accounts. Here is something you could try:
database
.ref("main/accounts")
.child(userId)
.once("value", snapshot => {
// check if snapshot exists
// log your snapshot.val()
})
Also, as Doug suggested, I would strongly suggest using Firebase Authentication.

Best practice: Nested subscriptions to receive user data?

I'm developing an Ionic 2 mobile app using Firebase as backend. With Firebase, some authentication data is stored with firebase automatically (currently logged in user's id, email and password). The other user data (name, address, ...) is stored in my Firebase database.
To get the currently logged in user's data, I have to subscribe to Firebase's auth methode first. Using angularfire2 I do the following:
this.af.auth.subscribe(data => {
... // data.uid gives me the user's id
}
Now I know the user's id and can subscribe to my Firebase database to get the other user data by doing:
this.af.database.object('/users/'+userId).subscribe( userData => {
...
}
If I combine both it's a nested subscription looking like this:
this.af.auth.subscribe(data => {
this.af.database.object('/users/'+user.uid).subscribe( userData => {
...
}
}
This works, however, it doesn't feel right to have two nested subscriptions. How do you guys deal with this? What would be a "best practice approach" here?
This can be done by Rxjs mergeMap operator
this.af.auth.subscribe(user=> {
this.af.database.object('/users/'+user.uid).subscribe( userData => {
...
}
}
to
this.af.auth.mergeMap(user=>this.af.database.object('/users/'+user.uid))
.subscribe(userData){
...
}
To answer your question, mergeMap is used to avoid nested subscription and remaining stuff is your app specific logic.

Categories

Resources