6. Userボタン
サインアップの修正
サインアップ処理でユーザ名が取れていないので、その修正を実施。
Convexのパスワードドキュメントに従う
Convex Auth
Authentication library for your Convex backend
convexAuthのプロバイダにカスタムパスワードを追加することで実現する。
convex/auth.ts
import GitHub from "@auth/core/providers/github";
import Google from "@auth/core/providers/google";
import { Password } from "@convex-dev/auth/providers/Password";
import { convexAuth } from "@convex-dev/auth/server";
import { DataModel } from "./_generated/dataModel";
const CustomPassword = Password<DataModel>({
profile(params) {
return {
email: params.email as string,
name: params.name as string,
};
},
});
export const { auth, signIn, signOut, store } = convexAuth({
providers: [CustomPassword, GitHub, Google],
});
これで名前が登録される。 GitHubとGoogleの認証はデフォルトで登録されている。
ユーザボタン作成
avatarとdropdown-menuを導入
terminal
$ bunx --bun shadcn@latest add avatar dropdown-menu
ユーザ取得処理
convex/users.ts
import { getAuthUserId } from "@convex-dev/auth/server";
import { query } from "./_generated/server";
export const current = query({
args: {},
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
if (userId === null) {
return null;
}
return await ctx.db.get(userId);
},
});
src/features/auth/hooks/use-current-user.ts
import { useQuery } from "convex/react";
import { api } from "../../../../convex/_generated/api";
export const useCurrentUser = () => {
const data = useQuery(api.users.current);
const isLoading = data === undefined;
return { data, isLoading };
};
ログインアバター表示
src/features/auth/components/user-button.tsx
"use client";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useAuthActions } from "@convex-dev/auth/react";
import { Loader, LogOut } from "lucide-react";
import { useCurrentUser } from "../hooks/use-current-user";
export const UserButton = () => {
const { signOut } = useAuthActions();
const { data, isLoading } = useCurrentUser();
if (isLoading) {
return <Loader className="site-4 animate-spin text-muted-foreground" />;
}
if (!data) {
return null;
}
const { image, name } = data;
const avatarFallback = name!.charAt(0).toLocaleUpperCase();
return (
<DropdownMenu modal={false}>
<DropdownMenuTrigger className="outline-none relative">
<Avatar className="size-10 hover:opacity-75 transition">
<AvatarImage alt={name} src={image} />
<AvatarFallback className="bg-sky-500 text-white">
{avatarFallback}
</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent align="center" side="right" className="w-60">
<DropdownMenuItem
onClick={async () => {
await signOut();
location.reload();
}}
className="h-10"
>
<LogOut className="size-4 mr-2" /> Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
};
[Tips] ログアウトでリロードされない
手順どおりやってサインアウトしてもリロードされない問題が発生。 見返しても間違いがないのでissueを覗くと、直近で同じエラーが起きている人がいた。 β板なのでまだ色々変わっているのでしょうがない。
Not auto redirect after execute signOut function · Issue #92 · get-convex/convex-auth
My project use: "@auth/core": "^0.35.3", "@convex-dev/auth": "^0.0.71", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", "class-variance-a...
回避策として単純にログアウト後に手動でリロードすることだったので、 location.reload();
を追加して暫定対応