Skip to content

Settings and activity

14 results found

  1. 3 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    0 comments  ·  General » Hosting  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  2. 19 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  3. 2 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    An error occurred while saving the comment
    Alexandre Paradis commented  · 

    You can create a hosting configuration that redirects to a function. Ex.

    ```
    {
    "target": "my-cdn",
    "headers": [
    {
    "source": "/**",
    "headers": [
    {
    "key": "Cache-Control",
    "value": "no-cache, no-store, must-revalidate"
    },
    { "key": "X-Content-Type-Options", "value": "nosniff" }
    ]
    },
    {
    "source": "**/*.@(jpg|jpeg|gif|png|webp|svg|ico)",
    "headers": [
    {
    "key": "Cache-Control",
    "value": "public, max-age=2592000, s-maxage=7776000"
    }
    ]
    }
    ],
    "rewrites": [
    {
    "source": "**",
    "function": "cdn",
    "region": "northamerica-northeast1"
    }
    ]
    },
    ```

    This is the function I'm using to serve images from a Firebase Storage bucket:

    ```
    import { error as logError } from 'firebase-functions/logger';
    import { onRequest } from 'firebase-functions/v2/https';
    import { Agent, get as httpsGet } from 'https';
    import { initializeFirebaseAdminApp } from '../infrastructure/firebase/initializeAdminApp';
    import { initializeExpressApp } from '../infrastructure/express/initializeApp';
    import { Request, Response } from 'express';
    import { lookup } from 'mime-types';

    initializeFirebaseAdminApp();
    const expressApp = initializeExpressApp('cdn');

    // Configure persistent connection
    const agent = new Agent({ keepAlive: true });

    // Set CDN caching duration in seconds
    const cacheMaxAge = 2592000; // 30 days
    const cacheSMaxAge = 7776000; // 90 days

    const allowedPrefix = '/';
    const isUrlAllowed = (url: string): boolean => url.startsWith(allowedPrefix);

    // Get firebase URL from received request
    const getFirebaseUrl = (url: string): string => {
    if (!isUrlAllowed(url)) {
    logError('URL is not allowed');
    throw new Error('URL is not allowed');
    }
    // Configure source image URLs. This assumes that we store images on Firebase Storage
    const projectId = process.env.GCLOUD_PROJECT;
    const pathSeparator = '%2F';
    const sourcePrefix = `https://firebasestorage.googleapis.com/v0/b/${projectId}-cdn/o/`;
    const sourceSuffix = `?alt=media`;

    const urlNoPrefix = url.slice(allowedPrefix.length);
    const sourceKey = urlNoPrefix.replace(/\//g, pathSeparator);
    return `${sourcePrefix}${sourceKey}${sourceSuffix}`;
    };

    expressApp.get('*', ({ url }: Request, response: Response) => {
    const firebaseUrl = getFirebaseUrl(url);
    httpsGet(firebaseUrl, { agent }, (res) => {
    const statusCode = res.statusCode || 404;
    const headerPipe = response;
    if (statusCode < 400) {
    headerPipe.set(
    'Cache-Control',
    `public, max-age=${cacheMaxAge}, s-maxage=${cacheSMaxAge}`,
    );
    const contentType = lookup(url);
    if (contentType) {
    headerPipe.set('Content-Type', contentType); // Some images were saved on Google Storage with a wrong content-type, so we try to set the good one here!
    }
    }
    headerPipe.status(statusCode);
    return res.pipe(headerPipe);
    });
    });

    export const cdn = onRequest(
    { region: ['northamerica-northeast1'] },
    expressApp,
    );

    ```

  4. 5 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    0 comments  ·  General » Other  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  5. 5 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    0 comments  ·  General » Hosting  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  6. 2 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis shared this idea  · 
  7. 29 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  8. 24 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  9. 42 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    1 comment  ·  General » Crashlytics  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  10. 87 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  11. 240 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  12. 12 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    1 comment  ·  General » Hosting  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  13. 17 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    0 comments  ·  General » Hosting  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  · 
  14. 34 votes

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)

    We’ll send you updates on this idea

    2 comments  ·  General » Firestore  ·  Admin →
    How important is this to you?

    We're glad you're here

    Please sign in to leave feedback

    Signed in as (Sign out)
    Alexandre Paradis supported this idea  ·