npm package: @firefuse/nextjs
Description: Firefuse nextjs library
Author: Firefuse
Latest version: 0.2.2

<h1 align="center">
  <br>
  <a href="https://firefuse.io"><img src="https://firefuse.io/_static/icons/firefuse.svg" alt="Firefuse"></a>
</h1>

<h4 align="center">Firebase authentication on steroids.</h4>

<p align="center">
    <a href="https://github.com/1devstudio/firefuse-react/commits/master">
    <img src="https://img.shields.io/github/last-commit/1devstudio/firefuse-react.svg?style=flat-square&logo=github&logoColor=white"
         alt="GitHub last commit">
    </a>
    <a href="https://github.com/1devstudio/firefuse-react/issues">
    <img src="https://img.shields.io/github/issues-raw/1devstudio/firefuse-react.svg?style=flat-square&logo=github&logoColor=white"
         alt="GitHub issues">
    </a>    
    <a href="https://github.com/1devstudio/firefuse-react/pulls">
    <img src="https://img.shields.io/github/issues-pr-raw/1devstudio/firefuse-react.svg?style=flat-square&logo=github&logoColor=white"
         alt="GitHub pull requests">
    </a>
</p>

<p align="center">
  <a href="#installation">Installation</a> •
  <a href="#contributing">Contributing</a> •
  <a href="#credits">Credits</a> •
  <a href="#support">Security</a> •
</p>

---

## Installation

### Add Firefuse to your project

```sh
npm install @firefuse/nextjs
```

## Usage in the application

### Configure Firefuse

Create firefuse.config.ts file and set following content.

```ts
import Firefuse from '@firefuse/nextjs';

const baseUrl = process.env[]

Firefuse.init({
  // this is url used by you app
  baseUrl: 'https://your-url.com',
  // Keep it false for your production, it can display some additional information if you notice any errros with authentication flow
  debug: true|false,
  // Firebase api key, you can find it in the firebase config
  apiKey: Env.getOrThrow('FIREFUSE_APP_API_KEY'),
  // This is firefuse application subdomain ex. your-app.firefuse.io, you should set just your-app
  applicationDomain: Env.getOrThrow('FIREFUSE_APP_APPLICATION_DOMAIN'),
  // These are necessary service account fields, you can find it in service account json
  serviceAccount: {
    project_id: Env.getOrThrow('APP_FIREBASE_PROJECT_ID'),
    private_key: Env.getOrThrow('APP_FIREBASE_ADMIN_PRIVATE_KEY').replace(
      /\\n/g,
      '\n'
    ),
    client_email: Env.getOrThrow('APP_FIREBASE_ADMIN_CLIENT_EMAIL'),
    private_key_id: Env.getOrThrow('APP_FIREBASE_ADMIN_PRIVATE_KEY_ID'),
  },
});

```

Create a instrumenation.ts file with the following content:

```ts
export async function register() {
  await import("./firefuse.config");
}
```

### Create proxy

Add proxy.ts file with the following content.

```tsx
import { firefuseAuthMiddleware } from "@firefuse/nextjs/server";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export const config = {
  matcher: [
    /*
     * Match all paths except for:
     * 3. /_next (Next.js internals)
     * 4. /_static (inside /public)
     * 5. all root files inside /public (e.g. /favicon.ico)
     */
    "/((?!_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)",
  ],
};

export default async function proxy(req: NextRequest) {
  // This sets necessary endpoints
  const response = await firefuseAuthMiddleware(req);

  if (response) {
    return response;
  }

  return NextResponse.next();
}
```

### Set the firebase auth configuration

```tsx
import { getAuth } from "firebase/auth";
import { initializeApp } from "firebase/app";

/**
 * Depends on your project setup, you may want to use firebase config directly
 * or like here via environment variables.
 */
export const firebaseConfig = {
  apiKey: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_API_KEY'),
  authDomain: Env.getOrThrow('NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN'),
  projectId: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_PROJECT_ID'),
  storageBucket: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET'),
  messagingSenderId: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID'),
  appId: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_APP_ID'),
  measurementId: Env..getOrThrow('NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID'),
};

const firebaseApp = initializeApp(firebaseConfig);

const firebaseAuth = getAuth(firebaseApp);
// here init firestore, analytics etc.

export { firebaseAuth };
```

### Use the `FirefuseProvider`

AuthProvider let you access user in client components.

```tsx
// layout
import type { ReactNode } from "react";
import { AuthProvider } from "./auth-provider";

export default function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  return <AuthProvider>{children}</AuthProvider>;
}

// AuthProvider
("use client");

import { FirefuseAuthProvider } from "@firefuse/nextjs/client";
import { initFirebaseClient } from "../../lib/firebase-client";
import { firebaseAuth } from "./firebase.ts";

export function AuthProvider({ children }: { children: ReactNode }) {
  return (
    <FirefuseAuthProvider firebaseAuth={firebaseAuth}>
      {children}
    </FirefuseAuthProvider>
  );
}
```

### Provide authentication check for specific pages

This will let you access a user object with server components.

```
import { AuthPageProps, withPageAuthenticated } from "@firefuse/nextjs/server";

const ManagePage = async ({ user }: AuthPageProps) => {
  return <div>Manage</div>;
}

export default withPageAuthenticated(ManagePage, () => '/manage');
```

### Check if user is authenticated

```tsx
import React from "react";
import { useAuth } from "@firefuse/react";

const Home = () => {
  const { user, logout } = useAuth();

  return (
    <div>
      {user ? (
        <div>
          <h1>Welcome {user.displayName}</h1>
          <button onClick={() => logout()}>Logout</button>
        </div>
      ) : (
        <div>
          <h1>Welcome Guest</h1>
        </div>
      )}
    </div>
  );
};
```

#### Debugging

To get more details in the dev console you can also provide additional param `debug`.

```tsx
<FirefuseProvider {...otherParams} debug={true}>
  <h1>Firefuse</h1>
</FirefuseProvider>
```

## Contributing

We are open to any contributions. Just fork the project, make your changes and open a pull request.

## Credits

This project is developed and maintained by [Firefuse team](https://firefuse.io).

## Security

If you discover any security related issues, please email [info@firefuse.io](mailto:info@firefuse.io) instead of using the issue tracker.