absent-sapphire
absent-sapphire10mo ago

Why useDelete calls getIdentity from auth-provider?

Hey there. I'm facing a wired problem. I have a table that has an actions column with a delete button that calls useDelete under the hood. Apparantly each time this button rendered (for each row) it calls ["getUserIdentity"] query. You can see in the first image that the query is subscribed in 12 places, when I remote the delete button it becoms 2. Why useDelete needs to know the user identity? I've looks at the code but can't find where you call getIdentity from auth-provider. This is the delete button, just calls useDelete, nothing fancy:
const DeleteButton = () => {
const { mutate } = useDelete();
return (
<button onClick={() => mutate({ resource: "users", id: 1 })}>delete</button>
);
};
const DeleteButton = () => {
const { mutate } = useDelete();
return (
<button onClick={() => mutate({ resource: "users", id: 1 })}>delete</button>
);
};
No description
19 Replies
kapa.ai
kapa.ai10mo ago
Hi @amirhhashemi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The useDelete hook itself does not directly call the getIdentity method from the auth provider. However, if you're using a <DeleteButton> component from refine, it uses the useCan hook internally to handle authorization. This hook checks if the current user has the permission to perform the delete action. This is where the getIdentity method might be called. Here's a snippet from the DeleteButton component in the @refinedev/antd package:
export const DeleteButton: React.FC<DeleteButtonProps> = ({
...
}) => {
...

const { data } = useCan({
resource: resourceName,
action: "delete",
params: { id, resource },
queryOptions: {
enabled: accessControlEnabled,
},
});

if (accessControlEnabled && hideIfUnauthorized && !data?.can) {
return null;
}

...
};
export const DeleteButton: React.FC<DeleteButtonProps> = ({
...
}) => {
...

const { data } = useCan({
resource: resourceName,
action: "delete",
params: { id, resource },
queryOptions: {
enabled: accessControlEnabled,
},
});

if (accessControlEnabled && hideIfUnauthorized && !data?.can) {
return null;
}

...
};
Source (https://refine.dev/blog/refine-pixels-6/) As you can see, the useCan hook is used to decide the authorization status. If the accessControlEnabled is true and the user is unauthorized (!data?.can), the component returns null, effectively hiding the delete button. If you're not using the <DeleteButton> component and are still experiencing this issue, it might be due to some other part of your code. You might want to check other places where you're using the getIdentity method or the useCan hook. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@930177741104500737> kapa.ai is still learning and improving, please let us know how it did by reacting below
absent-sapphire
absent-sapphire10mo ago
@kapa.ai I'm not using the <DeleteButton> component and I'm not using useCan or useIdentity in a relevant component. But in the docs you pass a meta.canDelete property to resources prop in the <Refine> component. I've removed it. Could it be the cause of the problem?
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, the meta.canDelete property in the resources prop of the <Refine> component could be the cause of the issue. The meta.canDelete property is used to control whether a delete button should be displayed on the edit page of a resource. If meta.canDelete is set to true, the delete button will be displayed. If it's set to false or not provided, the delete button will not be displayed. Here's an example of how it's used:
<Refine
resources={[
{
name: "posts",
list: "/posts",
create: "/posts/create",
edit: "/posts/edit/:id",
meta: {
canDelete: true,
},
},
]}
/>
<Refine
resources={[
{
name: "posts",
list: "/posts",
create: "/posts/create",
edit: "/posts/edit/:id",
meta: {
canDelete: true,
},
},
]}
/>
Source (https://refine.dev/blog/react-admin-panel/) When meta.canDelete is set to true, refine's <Edit> component uses this value to decide whether to show the delete button in the edit form or not. If you've removed the meta.canDelete property and are still experiencing the issue, it might be due to some other part of your code. You might want to check other places where you're using the useDelete hook or the DeleteButton component. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@930177741104500737> kapa.ai is still learning and improving, please let us know how it did by reacting below
absent-sapphire
absent-sapphire10mo ago
@kapa.ai But I'm not using <Edit> and any component from the component libraries that refine supports. Anywhere else uses meta.canDelete ?
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The meta.canDelete property is primarily used in the context of the <Edit> component in refine's component libraries (Ant Design, Material-UI, and Chakra UI). It's used to decide whether to display a delete button on the edit page of a resource. If you're not using the <Edit> component or any other component from refine's supported libraries, and you're not using the meta.canDelete property anywhere else in your code, then it's unlikely that this property is causing the issue. The useDelete hook itself does not use the meta.canDelete property. It's used to pass additional information to data provider methods for customizing the data provider methods for specific use cases or generating GraphQL queries using plain JavaScript Objects (JSON). Here's an example of how it's used:
const { mutate } = useDelete();

mutate({
meta: {
headers: { "x-meta-data": "true" },
},
});
const { mutate } = useDelete();

mutate({
meta: {
headers: { "x-meta-data": "true" },
},
});
Source (https://refine.dev/docs/api-reference/core/hooks/data/useDelete/) If you're still experiencing the issue, it might be due to some other part of your code. You might want to check other places where you're using the useDelete hook or the DeleteButton component. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@930177741104500737> kapa.ai is still learning and improving, please let us know how it did by reacting below
absent-sapphire
absent-sapphire10mo ago
@kapa.ai I've narrowed down the issue to the useDelete hook. I don't render anything else in the screen but still the ["getUserIdentity"] query is being called for each button.
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Based on the information provided in the extracts, the useDelete hook itself does not directly call the getIdentity method from the auth provider. It's primarily used to delete a record and returns mutation functions for that purpose. Here's an example of its usage:
const DeleteButton = () => {
const { mutate } = useDelete();
return (
<button onClick={() => mutate({ resource: "users", id: 1 })}>delete</button>
);
};
const DeleteButton = () => {
const { mutate } = useDelete();
return (
<button onClick={() => mutate({ resource: "users", id: 1 })}>delete</button>
);
};
Source (https://refine.dev/docs/tutorial/adding-crud-pages/headless/add-delete-feature/) If the useDelete hook is causing the ["getUserIdentity"] query to be called for each button, it might be due to some other part of your code or a specific behavior of your data provider or auth provider. Without more specific information about your implementation, it's hard to pinpoint the exact cause. I would recommend checking your data provider and auth provider implementations, as well as any other parts of your code that might be interacting with these providers. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@930177741104500737> kapa.ai is still learning and improving, please let us know how it did by reacting below
absent-sapphire
absent-sapphire10mo ago
@kapa.ai What do you mean by "specific behavior of your data provider or auth provider." This is my auth-provider:
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I'm sorry, but I can't provide a specific answer without seeing the code for your auth provider. What I meant by "specific behavior of your data provider or auth provider" is that the way these providers are implemented can affect how hooks like useDelete behave. For example, if your auth provider's getIdentity method is called every time a request is made to the data provider, this could explain why the ["getUserIdentity"] query is being called for each button. Here's an example of an auth provider implementation:
import { AuthBindings } from "@refinedev/core";

const authProvider: AuthBindings = {
getIdentity: async () => {
const user = localStorage.getItem("auth");

if (user) {
const { email, roles } = JSON.parse(user);

return { email, roles };
}

return null;
},
// other methods...
};
import { AuthBindings } from "@refinedev/core";

const authProvider: AuthBindings = {
getIdentity: async () => {
const user = localStorage.getItem("auth");

if (user) {
const { email, roles } = JSON.parse(user);

return { email, roles };
}

return null;
},
// other methods...
};
Source (https://refine.dev/docs/tutorial/understanding-authprovider/create-authprovider/) In this example, the getIdentity method is called to get the user's identity from the local storage. If your auth provider is implemented in a similar way, it should not be causing the ["getUserIdentity"] query to be called for each button. If you're still experiencing the issue, I would recommend checking your data provider implementation, as well as any other parts of your code that might be interacting with these providers. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@930177741104500737> kapa.ai is still learning and improving, please let us know how it did by reacting below
absent-sapphire
absent-sapphire10mo ago
@kapa.ai No I don't call any auth-provider's method in my data-provider. I have an access-control-provider too but it also doesn't use auth-provider's methods
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: @amirhhashemi That's a great question, but unfortunately I am only capable of responding to a maximum of five questions per thread. Don't hesitate to create a new thread for any further questions you have though. I'm here to help!
Omer
Omer10mo ago
Hey @amirhhashemi , the issue is with the Audit Log Provider calling the getUserIdentity function. In this line: https://github.com/refinedev/refine/blob/next/packages/core/src/hooks/auditLog/useLog/index.ts#L85, we noticed that the query is enabled even when no auditLogProvider is given, because its default is an empty object '{}'. We can solve this issue by checking if the 'create' method of auditLogProvider is different from undefined. If you'd like, you can create a PR or open a GitHub issue for the community to address.
absent-sapphire
absent-sapphire10mo ago
Hey @Omer . Thank you for the help. I was going to open an Issue but I saw a commit that addresses it. Looking forward for it being shipped in the next release.
Omer
Omer10mo ago
Hey @amirhhashemi , We've released @refinedev/core@4.44.7 🥁 https://github.com/refinedev/refine/releases/tag/%40refinedev%2Fcore%404.44.7
GitHub
Release @refinedev/core@4.44.7 · refinedev/refine
Patch Changes #5138 0e22d5804b2 Thanks @aliemir! - Prevent authProvider.getIdentity to be called in useLog if auditLogProvider is not defined.