next js api 直接从客户端路由或调用 firestore

next js api route or call firestore directly from client side

嗨,我是 next js 的新手,有几个关于使用 firebase 身份验证客户端和服务器端的问题。我的项目中同时设置了 firebase admin 和 firebase client sdks。我有一个注册页面用户路由。他们填写姓名电子邮件和密码。 当用户在注册页面上提交表单时,我正在使用客户端通过电子邮件和密码 createUserWithEmailAndPassword 进行身份验证。

问题: [1]

我想在创建用户时将用户名和 uid 的身份验证响应保存到 firestore 数据库。我应该在发生身份验证响应时在同一个提交处理程序中执行此操作吗?

  const onSignup = async ({ email, password }: Tfields) => {
    try {
      const response = await auth.signup(email, password);
      / *** DO I save to firestore DB here ? **/
     // route to authenticated page
      router.push("/account");
    } catch (error) {
   
      });
    }
  };  

[2] 如果从上面的处理程序调用 firestore,我应该直接使用 firebase 客户端 sdk 调用 firestore,还是应该在 nextjs 中创建一个名为 createDBUser 的 api 路由并调用 api 来自处理程序。使用 api 而不是直接使用客户端 sdk 连接到 firestore 会不会更安全?

[3] 示例授权路由,如 /account 这本质上是构建时的 SSG。 起初这不会在页面上显示任何内容,这对 SEO 不是很友好。只有 header SEO 组件一开始是可见的,直到 firebase 客户端检查发生?

const Account = () => {
  const [user, setUser] = useState<any>(null);

  const handleUser = (user) => {
   setuser(user)
  }

   useEffect(() => {
     const unsubscribe = onIdTokenChanged(getAuth(), handleUser);
   return () => unsubscribe();
  }, []);

  return (
    <div>
      <Head>
        <title>Authorized User page</title>
        <meta
          name="description"
          content="this is john doe's page with all his account pages"
        />
      </Head>
      {user && <div>
          <div>This is a authenticated account page</div>
      </div> }
    </div>
  );
};


export default Account;

或者我是否应该在帐户页面中使用 getServerSideProps 来检查用户是否已登录,而不是在 useEffect 中执行此操作。这不会在将所有内容提供给用户之前在服务器上呈现所有内容吗?我也可以在 seo header 中注入用户名,因为它会事先在服务器上呈现。

直接或通过服务器与 Firestore 交互取决于您的情况,并且意见可能会有所不同。但是否值得添加另一个 API 路由,验证用户令牌,然后在可以使用 security rules 直接保护数据时将数据添加到 Firestore?是的,您可以在 createUserWithEmailAndPassword() 创建用户后立即将数据添加到 Firestore。

如果您需要对更新文档或任何操作进行任何类型的速率限制,那么通过您的 API 路由 Firestore 请求会很有用。

对于服务器端呈现的 Web 应用程序,我建议使用 sessions cookies,这样您就可以在呈现之前对用户进行身份验证。在这里,您必须使用 Admin SDK 验证 cookie,并获取数据以在页面呈现之前显示。