Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google cloud/firebase storage Error: Cannot sign data without `client_email`. ... name: 'SigningError'

Im trying to get a signedurl from a file in firebase/gc storage. All other solutions that i could find was to create a service account, download the service key, and use it in my app, but ive done that, and im still getting the error. Ive followed this advice also and added relevant roles to my service account SigningError with Firebase getSignedUrl().

The client_email property is in the service key that im using.

Pretty new to service accounts and gc so i may be missing something simple.

I am able to list the buckets, and all other requests to cloud firestore are working. Its just the signedurl for specific files is proving very difficult to retrieve.

Been driving me a bit loopy so any help would be great.

Heres my code.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const { Storage } = require('@google-cloud/storage');

const serviceAccount = require('./emom-84ee4-firebase-adminsdk-2309z-aab93226ec.json');
const keyfileName = require('./emom-84ee4-ac9e94667d5e.json');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://emom-84ee4.firebaseio.com"
});

const storage = new Storage({
    projectId: 'emom-84ee4',
    keyFileName: keyfileName,
    // TRIED THIS ALSO => keyFileName: serviceAccount
});

const typeDefs = gql`
    type DownloadURL {
        url: String
    }

    type Comment {
        artist: String,
        comment: String,
        userId: String,
        replies: [Comment]
    }

    type Track {
        album: String,
        artist: String,
        artistId: String,
        description: String,
        genre: String,
        id: ID,
        title: String,
        duration: Int,
        comments: [Comment]
    }
    type User {
        artist: String,
        artistImageUrl: String,
        artistName: String,
        bio: String,
        location: String,
        userId: String,
        website: String
    }
    type Query {
        tracks: [Track]
        users: [User]
        downloadUrl: DownloadURL
    }
`

const resolvers = {
    Query: {
        async tracks() {
            const tracks = await admin
            .firestore()
            .collection('tracks')
            .get();
        return tracks.docs.map(track => track.data());
    },
    async users() {
        const users = await admin
            .firestore()
            .collection('users')
            .get();
            return users.docs.map(user => user.data());
    },
    // ISSUE HAPPENING HERE
    async downloadUrl() {
        try {
            const signedUrl = await storage
                .bucket('emom-84ee4.appspot.com')
                .file('tracks/ds5MaDn5ewxxvV0CK9GG.mp3')
                .getSignedUrl({ action: 'read', expires: '10-25-2022' });
            const url = signedUrl;
            console.log(url)
            return url;
        } catch (error) {
            console.error(error);
        }
    }
    }
}

const app = express();
const server = new ApolloServer({ typeDefs, resolvers });

server.applyMiddleware({ app, path: '/', cors: true });

exports.graph = functions.https.onRequest(app);
like image 907
bcooley1983 Avatar asked Nov 12 '20 11:11

bcooley1983


1 Answers

I was getting "Cannot sign data without client_email" error when running firebase emulators:start.

I fixed it by setting up a service account and downloading the service account .json credentials file as service_account.json, then running GOOGLE_APPLICATION_CREDENTIALS="service_account.json" firebase emulators:start

like image 101
cgenco Avatar answered Sep 23 '22 02:09

cgenco