Получение изображения из хранилища Firebase с использованием next/image приводит к получению кода состояния 400

Я использую компонент NextJS Image следующим образом:

      <Image src="https://firebasestorage.googleapis.com/v0/b/africatech-7cf1b.appspot.com/o/images%2F1606851317444_impact-logo-sq-Owen-Hancock.png?alt=media&token=35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb" layout="fill" />

Локально это работает, а в DOM выглядит так:

      <img alt="Company logo" src="/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=3840&amp;q=75" decoding="async" sizes="(max-width: 640px) 640px, (max-width: 750px) 750px, (max-width: 828px) 828px, (max-width: 1080px) 1080px, (max-width: 1200px) 1200px, (max-width: 1920px) 1920px, (max-width: 2048px) 2048px, 3840px" srcset="/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=640&amp;q=75 640w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=750&amp;q=75 750w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=828&amp;q=75 828w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1080&amp;q=75 1080w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1200&amp;q=75 1200w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1920&amp;q=75 1920w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=2048&amp;q=75 2048w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=3840&amp;q=75 3840w" style="visibility: visible; position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%;">

Однако при производстве он не загружает изображение. Есть сообщение 400:

      GET https://launchafrica.io/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&w=1920&q=75 400

Похоже, это из-за того, что параметр "url" недопустим.

В моем next.config.js Я настроил это:

      images: { domains: ['firebasestorage.googleapis.com'], },

Может ли кто-нибудь помочь мне разобраться, как использовать next/imageс образом, размещенным в хранилище Firebase в рабочей среде? Как локально загружается нормально.

5 ответов

Вам необходимо добавить приведенный ниже код в файл next.config.js:

      ...
images: {
    domains: ['firebasestorage.googleapis.com'],
},
...

Есть ли шанс, что вы также разместите это на хостинге Firebase? У меня была эта проблема, и я понял, что мне нужно импортировать файл next.config.js в конфигурацию при инициализации NextJS:

      const customNextConfig = require('./next.config');

const server = next({
  dev: isDev,
  conf: customNextConfig,
});

...

моя проблема решена с

      images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**',
      },
    ],
  },

Я опоздал на тему, но надеюсь, что мой ответ поможет кому-то еще.

Добавления конфигурации домена в next.config.js недостаточно, вам нужно убедиться, что ваш «следующий» экземпляр захватит эту конфигурацию.

Итак, в моем случае, что я сделал, чтобы заставить его работать:

До

      const nextjsDistDir = join("src", require("./src/next.config.js").distDir);
const nextjsServer = next({
  dev: isDev,
  conf: {
    distDir: nextjsDistDir
  }
});

После

      const nextjsDistDir = join("src", require("./src/next.config.js").distDir);
const nextjsServer = next({
  dev: isDev,
  conf: {
    distDir: nextjsDistDir,
    images: {
      domains: ['firebasestorage.googleapis.com'],
    }
  }
});

Оставив это здесь для потомков (по состоянию на 21 декабря 2021 г.): похоже, это связано с тем, что NextJS (когда он начал использовать npm start) фактически не использует файл next.config.js. Глядя на https://github.com/vercel/next.js/blob/canary/packages/next/cli/next-start.ts#L61, в передаются только каталог проекта, имя хоста и порт . https://github.com/vercel/next.js/blob/canary/packages/next/server/lib/start-server.ts#L44 . Поскольку параметр conf не передается, отсутствует файл images.domains.

В итоге мне пришлось написать свой собственный (на основе https://github.com/vercel/next.js/blob/canary/examples/custom-server-express/server.js ):

      const port = parseInt(process.env.PORT, 10) || 5000
const listen = process.env.LISTEN_INTERFACE || '127.0.0.1';
const dev = process.env.NODE_ENV !== 'production';
const app = next({
    dev: dev,
    customServer: false,
    hostname: process.env.HOSTNAME || 'localhost',
    conf: {
        images: {
            domains: [process.env.NEXT_PUBLIC_IMAGE_DOMAIN]
        },
        trailingSlash: true,
    poweredByHeader: false
    }
})
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const container = express();
    
  container.all('*', (req, res) => {
    return handle(req, res)
  })
    
    const server = http.createServer(container);
  server.listen(port, listen);
});
Другие вопросы по тегам