strapi
strapi copied to clipboard
Can't add field in user (users-permissions)
Feature request
Please describe your feature request
- [ ] I have created my request on the Product Board before I submitted this issue
- [x] I have looked at all the other requests on the Product Board before I submitted this issue
Summary
I would like to add some extra fields in user like firstName and lastName but adding them using Content-Type Builder doesn't make them available in GraphQL API
Steps to reproduce the behavior
- Using the Content-Type Build, add a Text field in User
- Go on http://localhost:1337/graphql and check GraphQL documentation
- The added text field isn't exposed
Screenshots
firstName and lastName text fields added in user using Content-Type Builder:

Added fields not available in GraphQL API:

Why is it needed?
Since user is a central part for most authenticated API and adding extra fields or relations to user is a very common use case. For now, we have to manually write specific code to add extra fields (in addition to Content-Type Builder). Thanks @iicdii to remember me the way we do it in v3.
Suggested solution(s)
The added text field should be exposed, both on query and mutation.
Related issue(s)/PR(s)
None, since I have "transform" the current issue from "bug report" to "feature request" :wink:
You can just extend UsersPermissionsMe type with your custom fields.
path: src/index.js
'use strict';
module.exports = {
/**
* An asynchronous register function that runs before
* your application is initialized.
*
* This gives you an opportunity to extend code.
*/
register({ strapi }) {
const extensionService = strapi.plugin('graphql').service('extension');
extensionService.use(({ nexus }) => ({
types: [
nexus.extendType({
type: 'UsersPermissionsMe',
definition(t) {
// here define fields you need
t.string('testing');
},
}),
]
}));
},
/**
* An asynchronous bootstrap function that runs before
* your application gets started.
*
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*/
bootstrap({ strapi }) {},
/**
* An asynchronous destroy function that runs before
* your application gets shut down.
*
* This gives you an opportunity to gracefully stop services you run.
*/
destroy({ strapi }) {},
};
Hi @iicdii and thanks for your quick reply.
Just to be sure, the proposed solution is a workaround? The v3 behavior (where we just need to add fields using Content-Type builder) is the target?
Thanks again
I remember you had to add fields manually in UsersPermissionsMe type in v3 either like below.
// api/extensions/users-permissions/config/schema.graphql.js
module.exports = {
definition: `
extend type UsersPermissionsMe {
picture: String
country: String
}
`,
query: ``,
resolver: {},
};
I'm not sure if Strapi team want to generate UsersPermissionsMe type dynamically, because they have some security concerns and etc..
You are right @iicdii , I have that file in v3 (sorry I forgot). So now I have to do the same in v4, thanks a lot for explanations about how to do it :kissing_heart:
Still, I think that Content-Type Builder looks like the intuitive way to extend the user schema and I can't see any drawback (because it's just extra fields, no impact on existing, locked, ones).
However, this issue should now be considered as a feature request and so I will edit my original message to reflect that.
Again, thanks a lot for your help, explanations and quick reply :heart:
Can confirm: manually extending the schema works as expected :+1: One of my two show stopper is now solved :ok_hand:
This issue has been mentioned on Strapi Community Forum. There might be relevant details there:
https://forum.strapi.io/t/strapi-v4-cant-access-custom-fields-from-users-me-via-graphql/13744/2
You can just extend
UsersPermissionsMetype with your custom fields. path:src/index.js'use strict'; module.exports = { /** * An asynchronous register function that runs before * your application is initialized. * * This gives you an opportunity to extend code. */ register({ strapi }) { const extensionService = strapi.plugin('graphql').service('extension'); extensionService.use(({ nexus }) => ({ types: [ nexus.extendType({ type: 'UsersPermissionsMe', definition(t) { // here define fields you need t.string('testing'); }, }), ] })); }, /** * An asynchronous bootstrap function that runs before * your application gets started. * * This gives you an opportunity to set up your data model, * run jobs, or perform some special logic. */ bootstrap({ strapi }) {}, /** * An asynchronous destroy function that runs before * your application gets shut down. * * This gives you an opportunity to gracefully stop services you run. */ destroy({ strapi }) {}, };
Looks like this solutions doesn't work for relationships.
nexus.extendType({
type: "UsersPermissionsMe",
definition(t) {
t.string("name");
t.string("phone");
t.field("orders", {
type: "OrderRelationResponseCollection",
});
},
})
In my example, name and phone works well, but orders don't.
Hi @iicdii and @derrickmehaffy,
With your approbation, I guess some tags should be added to this issue:
issue-type: feature requestseverity: lowsource: plugin:users-permissions(or perhapssource: core:content-type-builder:man_shrugging: )status: confirmed
I would be very happy to do it myself but I haven't enough "karma" (yet) :stuck_out_tongue_closed_eyes:
Hi @iicdii and @derrickmehaffy,
With your approbation, I guess some tags should be added to this issue:
issue-type: feature requestseverity: lowsource: plugin:users-permissions(or perhapssource: core:content-type-builderman_shrugging )status: confirmedI would be very happy to do it myself but I haven't enough "karma" (yet) stuck_out_tongue_closed_eyes
We don't allow anyone but us and selected moderators to add labels yes :P
While this was opened as a feature request, it's actually more like a bug, this part of the schema should be automatically generated. Assuming we can limit the population which I believe should be possible.
Thanks a lot for adding tags (and seriously considering a potential futur implementation for it) :pray:
While this was opened as a feature request, it's actually more like a bug
In fact it was created as a bug report (because I forgot I was forced to add some custom code in my previous v3 setup to make it work) and, after precious @iicdii advises, I "transform" :magic_wand: it as a feature request by editing my original message :shushing_face:
I'm proud to see that the result of my "transformation" is so "plausible" that no one can detect it now :laughing:
You can just extend
UsersPermissionsMetype with your custom fields. path:src/index.js'use strict'; module.exports = { /** * An asynchronous register function that runs before * your application is initialized. * * This gives you an opportunity to extend code. */ register({ strapi }) { const extensionService = strapi.plugin('graphql').service('extension'); extensionService.use(({ nexus }) => ({ types: [ nexus.extendType({ type: 'UsersPermissionsMe', definition(t) { // here define fields you need t.string('testing'); }, }), ] })); }, /** * An asynchronous bootstrap function that runs before * your application gets started. * * This gives you an opportunity to set up your data model, * run jobs, or perform some special logic. */ bootstrap({ strapi }) {}, /** * An asynchronous destroy function that runs before * your application gets shut down. * * This gives you an opportunity to gracefully stop services you run. */ destroy({ strapi }) {}, };Looks like this solutions doesn't work for relationships.
nexus.extendType({ type: "UsersPermissionsMe", definition(t) { t.string("name"); t.string("phone"); t.field("orders", { type: "OrderRelationResponseCollection", }); }, })In my example,
nameandphoneworks well, butordersdon't.
is their any way to make it work
I have the same issue as @ntkien2192 and @vitor-mariano, How can you extend you query to relations, components and dynamic zones.
Maybe it helps someone. This is how I add a relation to UsersPermissionsMe.
(I don't know if it's the best solution but it does work.)
"use strict";
module.exports = {
register({ strapi }) {
const { toEntityResponseCollection } = strapi.plugin("graphql").service("format").returnTypes;
const extensionService = strapi.plugin("graphql").service("extension");
extensionService.use(({ nexus }) => ({
types: [
nexus.extendType({
type: "UsersPermissionsMe",
definition(t) {
t.field("solvedQuizzes", {
type: "QuizRelationResponseCollection",
resolve: async (root, args) => {
const userData = await strapi.db.query("plugin::users-permissions.user").findOne({
select: [], // solvedQuizzes are there due to populate
where: { id: root.id },
populate: { solvedQuizzes: true },
});
return toEntityResponseCollection(userData.solvedQuizzes ?? [], {
args,
resourceUID: "api::institution.quiz",
});
},
});
},
}),
],
}));
},
bootstrap(/*{ strapi }*/) {},
};
Thanks for the inspiration, I was able to add the user role relation to the me query based on your example. My code for completeness.
register({ strapi }) {
const extensionService = strapi.plugin("graphql").service("extension");
extensionService.use(({ nexus }) => ({
types: [
nexus.extendType({
type: "UsersPermissionsMe",
definition(t) {
// here define fields you need
t.field("role", {
type: "String",
resolve: async (root, args) => {
const userData = await strapi.db
.query("plugin::users-permissions.user")
.findOne({
select: [],
where: { id: root.id },
populate: { role: true },
});
return userData.role.type;
},
});
},
}),
],
}));
},
Would this be adjustable to solve the issue with user roles not coming back? https://github.com/strapi/strapi/issues/11957
This issue has been mentioned on Strapi Community Forum. There might be relevant details there:
https://forum.strapi.io/t/cannot-query-field-firstname-on-type-userspermissionsuser/17884/1
This issue has been mentioned on Strapi Community Forum. There might be relevant details there:
https://forum.strapi.io/t/cannot-query-field-firstname-on-type-userspermissionsuser/17884/2
This issue has been mentioned on Strapi Community Forum. There might be relevant details there:
https://forum.strapi.io/t/user-role-info-when-logging-in/18147/2
This issue has been mentioned on Strapi Community Forum. There might be relevant details there:
https://forum.strapi.io/t/strapi-v4-graphql-update-only-specific-collection-entries-with-authentication/18258/1
I have tried to modify the work around and add custom field's to the register mutation, this has not worked can any one point me in the right direction, i need to be able to fill in the user details on sign up.
register({ strapi }) { const extensionService = strapi.plugin("graphql").service("extension"); extensionService.use(({ nexus }) => ({ types: [ nexus.extendType({ type: "UsersPermissionsRegisterInput", definition(t) { // here define fields you need t.string("firstname"); t.string("lastname"); }, }), ], })); },
What about the REST? Is there a way to retrieve these additional fields on user login? (/api/auth/local)
I added the function as indicated in ./src/index.js like this :
register({ strapi }) {
const extensionService = strapi.plugin('graphql').service('extension');
extensionService.use(({ nexus }) => ({
types: [
nexus.extendType({
type: 'UsersPermissionsMe',
definition(t) {
t.string('user_firstname');
},
}),
],
}));
}
I no longer have the error :
Cannot query field "user_firstname" on type "UsersPermissionsMe".
but I still have the following error:
Field "user_firstname" is not defined by type "UsersPermissionsRegisterInput".
I have these settings in Users-permissions for Authenticated user

and this for public user
Does anyone have an idea where the problem comes from ? Thanks
I added the function as indicated in
./src/index.jslike this :register({ strapi }) { const extensionService = strapi.plugin('graphql').service('extension'); extensionService.use(({ nexus }) => ({ types: [ nexus.extendType({ type: 'UsersPermissionsMe', definition(t) { t.string('user_firstname'); }, }), ], })); }I no longer have the error :
Cannot query field "user_firstname" on type "UsersPermissionsMe".but I still have the following error:
Field "user_firstname" is not defined by type "UsersPermissionsRegisterInput".I have these settings in Users-permissions for Authenticated user
and this for public user
![]()
Does anyone have an idea where the problem comes from ? Thanks
Solved this by adding this:
nexus.extendInputType({
type: 'UsersPermissionsRegisterInput',
definition(t) {
// here define fields you need
t.string('lastName');
},
}),
How would I go if I want to add an avatar for example ? Adding relations and strings are easy enough but I can't get files.