Error trying to set auto back up Firestore, cloud function - node.js

I am following this tutorial here: Tutorial
everything seems ok and it allows me to do everything in the tutorial, but when I run the function I get this error.
textPayload: "TypeError: Cannot read property 'charCodeAt' of undefined
at peg$parsetemplate (/workspace/node_modules/google-gax/build/src/pathTemplateParser.js:304:17)
at Object.peg$parse [as parse] (/workspace/node_modules/google-gax/build/src/pathTemplateParser.js:633:18)
at new PathTemplate (/workspace/node_modules/google-gax/build/src/pathTemplate.js:55:54)
at segments.forEach.segment (/workspace/node_modules/google-gax/build/src/pathTemplate.js:120:29)
at Array.forEach (<anonymous>)
at PathTemplate.render (/workspace/node_modules/google-gax/build/src/pathTemplate.js:114:23)
at FirestoreAdminClient.databasePath (/workspace/node_modules/#google-cloud/firestore/build/src/v1/firestore_admin_client.js:904:57)
at exports.scheduledFirestoreExport (/workspace/index.js:13:31)
at Promise.resolve.then (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:330:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
insertId: "000000-8410c5c7-8304-42b6-b2b6-dd55a54e8cab"
resource: {2}
timestamp: "2020-07-11T18:14:35.981Z"
severity: "ERROR"
labels: {1}
logName: "projects/b-b-b-app/logs/cloudfunctions.googleapis.com%2Fcloud-functions"
trace: "projects/b-b-b-app/traces/d7c07a715d0106225d9963ce2a046489"
receiveTimestamp: "2020-07-11T18:14:44.813410062Z"
}
I can't see what the problem may be.
I changed the buckets and the app ids like asked in the tutorial.
I am on a Blaze plan and can export the database to the bucket manually by using shell command and using
gcloud firestore export gs://bbbdata-backup
I am using the GCP console on the firebase site and using this code.
const firestore = require('#google-cloud/firestore');
const client = new firestore.v1.FirestoreAdminClient();
const bucket = 'gs://bbbdata-backup'
exports.scheduledFirestoreExport = (event, context) => {
const databaseName = client.databasePath(
process.env.GCLOUD_PROJECT,
'(default)'
);
return client
.exportDocuments({
name: databaseName,
outputUriPrefix: bucket,
// Leave collectionIds empty to export all collections
// or define a list of collection IDs:
// collectionIds: ['users', 'posts']
collectionIds: [],
})
.then(responses => {
const response = responses[0];
console.log(`Operation Name: ${response['name']}`);
return response;
})
.catch(err => {
console.error(err);
});
};

Following the tutorial referred by the OP I run into precisely the same error. Runtime used: Node.js 14.
Root cause of the issue: value of process.env.GCLOUD_PROJECT is undefined.
Workaround: Go to GCP console -> Home. Note your Project ID. Replace process.env.GCLOUD_PROJECT with the 'Project ID' string. The Cloud Function will then work as expected
Note: it appears to be a known issue that GCLOUD_PROJECT environment variable was missing in the Node.js 10 runtime. This bug report contains a lot of additional pointers: https://github.com/firebase/firebase-functions/issues/437

I had a similar issue last year, probably you are missing some permission, I would do it this way, hope this works for you:
import * as functions from 'firebase-functions'
import { auth } from 'google-auth-library'
export const generateBackup = async () => {
const client = await auth.getClient({
scopes: [
'https://www.googleapis.com/auth/datastore',
'https://www.googleapis.com/auth/cloud-platform'
]
})
const path = `YOUR_FOLDER_NAME_FOR_THE_BACKUP`
const BUCKET_NAME = `YOUR_BUCKET_NAME_HERE`
const projectId = await auth.getProjectId()
const url = `https://firestore.googleapis.com/v1beta1/projects/${projectId}/databases/(default):exportDocuments`
const backup_route = `gs://${BUCKET_NAME}/${path}`
return client.request({
url,
method: 'POST',
data: {
outputUriPrefix: backup_route,
// collectionsIds: [] // if you want to specify which collections to export, none means all
}
})
.catch(async (e) => {
return Promise.reject({ message: e.message })
})
}
You can then decide that is your trigger for this function and execute it accordingly.
Note: Go to the IAM section of your project and find the App Engine service account, you will need to add the role Cloud Datastore Import Export Admin, otherwise, It will fail.
You can read more about it here It's very detailed.
Cheers.

Related

Module not found: Can't resolve 'fs' on #google-cloud/storage

Getting the Module not found: Can't resolve 'fs' error when trying to list out buckets from GCP Storage.
import { Storage } from '#google-cloud/storage';
const googleCloud = new Storage({
keyFilename: '../../my-project-c1a44bf80be3.json',
projectId: 'my-project',
});
googleCloud.getBuckets().then((x: any) => console.log(x));
my-project-c1a44bf80be3.json (Download from GCP) exists and is the project level
Error:
event - compiled successfully
event - build page: /
wait - compiling...
error - ./node_modules/#google-cloud/storage/build/src/file.js:24:0
Module not found: Can't resolve 'fs'
null
Could not find files for / in .next/build-manifest.json
event - compiled successfully
The same error appears when using googleapis.
However, instead of ./node_modules/#google-cloud/storage/build/src/file.js:24:0 it's in the google-auth-library module that comes with the googleapis.
Added using yarn.
This usually happens when you import or reference firebase-admin in the client side, check your code for wrong imports where you might be calling
import * as firebase from "firebase-admin";
instead of
import firebase from "firebase";
I faced the same problem but this guide was the solution in my case.
As mentioned before, the problem is that the firebase-admin package is designed to run in a NodeJs environment and not on the client. Extending webpack.config.js or next.config.js with certain entries did not solve the problem for me.
I have noticed your are using NextJS. So the solution is to move the firebase-admin calls to the NextJS API which you can create within the /pages/api folder.
Here is a simple example to fetch user data from the client.
You need:
/src/lib/firebase.ts: firebase initialization
/src/pages/api/user.ts: NextJS API handler
/src/components/xyz.tsx: component on client, which calls the API
// /src/lib/firebase.ts
import admin from "firebase-admin";
import { cert } from "firebase-admin/app";
import certConfig from "./firebase-adminsdk-config.json"
admin.initializeApp({
credential: cert(certConfig)
});
console.log("Firebase initialized.");
export default admin;
// /src/pages/api/user.ts
import admin from 'lib/firebase'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const firebase = admin.firestore()
const collection = firebase.collection('users')
// get any data from requests body
const { user } = req.body
// perform your firebase collection call
const data = await collection.get(user.id)
// return data to client
res.status(200)
res.json({
success: true,
result: data
});
return res
}
On the client side then you just have to perform a GET to your own API
// /src/components/xyz.tsx
...
const onLogin = async (user) => {
const response = await fetch(`/api/users`, {
method: "GET",
body: JSON.stringify({ user }),
});
// data => { success: boolean, result: any }
const data = await response.json();
return data;
}
...
Posting the solution provided in the comments for visibility.
In your webpack configuration, you can indicate that certain modules
like fs should be stubbed out; at which point you should be able to
run this library client-side. For example:
node: {
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
...config.node,
fs: 'empty',
child_process : 'empty',
net : 'empty',
tls: 'empty',
}
The scenario you are describing is now being handled by Google. Although there is no ETA, the issue is being prioritized.

Could not load the default credentials? (Node.js Google Compute Engine)

I am trying to create a new vm using Nodejs client libraries of GCP, I followed the below link,
https://googleapis.dev/nodejs/compute/latest/VM.html#create
and below is my code
const Compute = require('#google-cloud/compute');
const {auth} = require('google-auth-library');
const compute = new Compute();
var cred = "<<<credential json content as string>>>";
auth.scopes = ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute'];
auth.jsonContent = JSON.parse(cred);
const config = {
machineType: 'n1-standard-1',
disks: [ {
boot: true,
initializeParams: { sourceImage: '<<<image url>>>' }
} ],
networkInterfaces: [ { network: 'global/networks/default' } ],
tags: [ { items: [ 'debian-server', 'http-server' ] } ],
auth: auth,
};
async function main() {
// [START gce_create_vm]
async function createVM() {
const zone = compute.zone('us-central1-c');
const vm = zone.vm('vm-name');
await vm.create(config).then(function(data) {
const vm = data[0];
const operation = data[1];
const apiResponse = data[2];
});
console.log(vm);
console.log('Virtual machine created!');
}
createVM().catch(function (err) {
console.log(err);
});
// [END gce_create_vm]
}
main();
when i run this, the error I am getting is
Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
at GoogleAuth.getApplicationDefaultAsync (D:\Click to deploy\src\c2dNodeGCP\node_modules\google-auth-library\build\src\auth\googleauth.js:155:19)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async GoogleAuth.getClient (D:\Click to deploy\src\c2dNodeGCP\node_modules\google-auth-library\build\src\auth\googleauth.js:487:17)
at async GoogleAuth.authorizeRequest (D:\Click to deploy\src\c2dNodeGCP\node_modules\google-auth-library\build\src\auth\googleauth.js:528:24)
My scenario is to take the service account credential from string variable rather than from env var or some other thing.
I can see that it is trying to take the default credential which is not there in my case.
I was able to achieve this in java, but here i am not able to do it. Any help will be appreciated.
In order to execute your local application using your own user credentials for API access temporarily you can run:
gcloud auth application-default login
You have to install sdk into your computer, that will enable you to run the code.
Then log in to your associated gmail account and you will be ready.
You can check the following documentation, to get more information.
Another option is to set GOOGLE_APPLICATION_CREDENTIALS to provide authentication credentials to your application code. It should point to a file that defines the credentials.
To get this file please follow the steps:
Navigate to the APIs & Services→Credentials panel in Cloud Console.
Select Create credentials, then select API key from the dropdown menu.
The API key created dialog box displays your newly created key.
You might want to copy your key and keep it secure. Unless you are using a testing key that you intend to delete later.
Put the *.json file you just downloaded in a directory of your choosing.
This directory must be private (you can't let anyone get access to this), but accessible to your web server code.
You can write your own code to pass the service account key to the client library or set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path of the JSON file downloaded.
I have found the following code that explains how you can authenticate to Google Cloud Platform APIs using the Google Cloud Client Libraries.
/**
* Demonstrates how to authenticate to Google Cloud Platform APIs using the
* Google Cloud Client Libraries.
*/
'use strict';
const authCloudImplicit = async () => {
// [START auth_cloud_implicit]
// Imports the Google Cloud client library.
const {Storage} = require('#google-cloud/storage');
// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = new Storage();
// Makes an authenticated API request.
async function listBuckets() {
try {
const results = await storage.getBuckets();
const [buckets] = results;
console.log('Buckets:');
buckets.forEach((bucket) => {
console.log(bucket.name);
});
} catch (err) {
console.error('ERROR:', err);
}
}
listBuckets();
// [END auth_cloud_implicit]
};
const authCloudExplicit = async ({projectId, keyFilename}) => {
// [START auth_cloud_explicit]
// Imports the Google Cloud client library.
const {Storage} = require('#google-cloud/storage');
// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
// const projectId = 'project-id'
// const keyFilename = '/path/to/keyfile.json'
const storage = new Storage({projectId, keyFilename});
// Makes an authenticated API request.
async function listBuckets() {
try {
const [buckets] = await storage.getBuckets();
console.log('Buckets:');
buckets.forEach((bucket) => {
console.log(bucket.name);
});
} catch (err) {
console.error('ERROR:', err);
}
}
listBuckets();
// [END auth_cloud_explicit]
};
const cli = require(`yargs`)
.demand(1)
.command(
`auth-cloud-implicit`,
`Loads credentials implicitly.`,
{},
authCloudImplicit
)
.command(
`auth-cloud-explicit`,
`Loads credentials explicitly.`,
{
projectId: {
alias: 'p',
default: process.env.GOOGLE_CLOUD_PROJECT,
},
keyFilename: {
alias: 'k',
default: process.env.GOOGLE_APPLICATION_CREDENTIALS,
},
},
authCloudExplicit
)
.example(`node $0 implicit`, `Loads credentials implicitly.`)
.example(`node $0 explicit`, `Loads credentials explicitly.`)
.wrap(120)
.recommendCommands()
.epilogue(
`For more information, see https://cloud.google.com/docs/authentication`
)
.help()
.strict();
if (module === require.main) {
cli.parse(process.argv.slice(2));
}
You could obtain more information about this in this link, also you can take a look at this other guide for Getting started with authentication.
Edit 1
To load your credentials from a local file you can use something like:
const Compute = require('#google-cloud/compute');
const compute = new Compute({
projectId: 'your-project-id',
keyFilename: '/path/to/keyfile.json'
});
You can check this link for more examples and information.
This other link contains another example that could be useful.

Timeout error awaiting promise in Lambda?

I am testing a Serverless lambda function and get a timeout error which I believe is due to an await promise().
module.exports.create = async (event) => {
const provider = event.requestContext.identity.cognitoAuthenticationProvider
....//stuff here where I split auth token to get ids...
const cognito = new AWS.CognitoIdentityServiceProvider({
apiVersion: "2016-04-18"
});
const getUserParams = {
UserPoolId: userPoolId,
Username: userPoolUserId
};
const data =JSON.parse(event.body)
const getUser = await cognito.adminGetUser(getUserParams).promise()
const params = {
Item:{
userId: event.requestContext.identity.cognitoIdentityId,
email: getUser, //!timeout issue probably here!
content: data
}
};
try {
const { Listing } = await connectToDatabase()
const listing = await Listing.create({userId: params.Item.userId, email: params.Item.email
In researching a solution, I have come across people splitting up the lambda into two functions so that they collectively pass the timeout. I do not know how to reference a lambda within a lambda, nor am I sure this is the correct approach.
You change the timeout for lambda function
default timeout for lambda function is 3 sec you can override in below the function code basic settings
For anyone googling this: turns out adminGetUser needs a NAT Gateway configured in order for it to be able to retrieve data from Cognito. I was getting a timeout error because it was not executing, period. Read here: https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/.

How can I change a VM/Instance label with GCP Cloud Function using node.js?

I am testing a Cloud Function in GCP and I want to modify labels of my compute instance with Cloud Function i.e. change label "status=active" to "status=tobedeleted".
Is there a way to do it with Cloud Function and node.js ?
Looks as if the method compute.instances.setLabels requires additional libraries ?
I already created Cloud Function to stop/start instances.
Here is the error :
resource: {…}
severity: "ERROR"
textPayload: "{ Error: Login Required
at Gaxios.request (/srv/node_modules/googleapis-common/node_modules/gaxios/build/src/gaxios.js:70:23)
at
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
response:
{ config:
{ url: 'https://www.googleapis.com/compute/v1/projects/wpress-v1/zones/us-central1-a/instances/instance-1/setLabels?labels%5Bis-scheduled%5D=manual',
method: 'POST',
paramsSerializer: [Function],
headers: [Object],
params: [Object],
validateStatus: [Function],
retry: true,
responseType: 'json',
retryConfig: [Object] },
data: { error: [Object] },
Then here is my code :
const Compute = require('#google-cloud/compute');
/*const compute = new Compute();*/
const {google} = require('googleapis');
/*const google = require('#google-cloud/googleapis');*/
var compute = google.compute('v1');
exports.setInstanceScheduleMode = (event, context, callback) => {
try {
const payload = _validatePayload(
JSON.parse(Buffer.from(event.data, 'base64').toString())
);
var request = {
project: 'wpress-v1',
zone: 'us-central1-a',
instance: 'instance-1',
labels: {
"is-scheduled": "manual"
},
auth: google.authClient,
};
compute.instances.setLabels(request, function(err, response) {
if (err) {
console.error(err);
return;
}
console.log(JSON.stringify(response, null, 2));
});
} catch (err) {
console.log(err);
callback(err);
}
};
// [END functions_start_instance_pubsub]
function _validatePayload(payload) {
if (!payload.zone) {
throw new Error(`Attribute 'zone' missing from payload`);
} else if (!payload.label) {
throw new Error(`Attribute 'label' missing from payload`);
}
else if (!payload.instance) {
throw new Error(`Attribute 'instance' missing from payload`);
}
return payload;
}
function authorize(callback) {
google.auth.getClient({
scopes: ['https://www.googleapis.com/auth/cloud-platform']
}).then(client => {
callback(client);
}).catch(err => {
console.error('authentication failed: ', err);
});
}
There's a good number of things going on in this code. This isn't a straightforward operation, and I do wish there were a few more examples in the documentation of how to do this.
First, it appears that the #google-cloud/compute idiomatic library doesn't support a setLabels function on its VMs object, so we're forced to use the node REST library, which isn't quite as easy to use. The code you have written seems to mix the two in a somewhat confusing way, but is mostly already using the REST API so we can start from there. For reference, the setLabels REST API documentation.
Second, the authentication error you are getting is because you haven't properly intilized the authClient for the REST API, in particular by granting it the correct scope. (Notably, the authorize() method is never called, unlike in the sample code). This needs to be called to at least request the https://www.googleapis.com/auth/compute scope, though the cloud-platform scope will also work, as it is more privileged. This is what is leading to your immediate authentication error.
It is also possible that you are running the cloud function as an IAM account without the necessary roles, but both the default compute engine and default app engine accounts should be able to do this, so it appears to be that the scopes aren't requested.
Finally, even if this was working, you would find that the setLabels method requires a fingerprint of the current label values, or it would return a CONDITION_FAILURE -- essentially, when you call setLabels you are fully replacing the labels on the instance, so the API wants to make sure two callers aren't competing at once.
All together, that leads us to this (for simplicity, I used an HTTP function, but of course you can use your existing trigger just as well):
const { google } = require('googleapis');
const computeClient = google.compute('v1');
exports.labelInstance = async (req, res) => {
// First, get the auth scope we need. Thankfully cloud functions runs with
// application default credentials, so we don't need to do anything with keys, etc
// as long as the service account we are configured to run as has the right permissions.
//
// We only need the compute scope, we don't need all of cloud-platform, so limit ourselves to that.
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/compute']
});
const authClient = await auth.getClient();
// Build our request
var baseRequest = {
project: 'YOUR-PROJECT-NAME',
zone: 'us-central1-a',
instance: 'instance-1',
auth: authClient
};
// We need to get the existing labels and fingerprint first.
return computeClient.instances.get(baseRequest).then(result => {
// We need all the fields from baseRequest again, and we want to keep the old labels.
// I'm sort of cheating here, since it isn't a deep copy, but it works within the
// scope of this function.
setRequest = baseRequest;
// As setLabels is a POST request, we need to put the parameters in the requestBody.
setRequest.requestBody = {
labels: result.data.labels || {},
labelFingerprint: result.data.labelFingerprint // Needed to avoid CONDITION_FAILURE
};
// And add our new label...
setRequest.requestBody.labels['my-new-label'] = 'my-new-value';
return computeClient.instances.setLabels(setRequest);
}).then(result => {
console.log('set done');
console.log(result);
return res.send('ok');
}).catch(error => {
console.error('Error!');
console.error(error);
return res.send('error');
});
};
In your original question you wanted to change a label. Obviously you can adjust the code above to remove any labels out of the set that is retrieved with the fingerprint that you like, you don't have to copy them all.
Also be aware that the above code doesn't actually wait for the operation to complete (as operations are asynchronous -- the result that is returned will likely be in the RUNNING state), you would need to further use the REST API to check on the status of the operation. I haven't done that as it is somewhat outside the scope of this question, but you can read about it here.
Google Cloud Platform documentation provides a detailed overview of instances.setLabels method, which is a part of Google's Node.js client library.
See the Node.js code sample mentioned in GCP documentation below:
// BEFORE RUNNING:
// ---------------
// 1. If not already done, enable the Compute Engine API
// and check the quota for your project at
// https://console.developers.google.com/apis/api/compute
// 2. This sample uses Application Default Credentials for authentication.
// If not already done, install the gcloud CLI from
// https://cloud.google.com/sdk and run
// `gcloud beta auth application-default login`.
// For more information, see
// https://developers.google.com/identity/protocols/application-default-credentials
// 3. Install the Node.js client library by running
// `npm install googleapis --save`
const {google} = require('googleapis');
var compute = google.compute('v1');
authorize(function(authClient) {
var request = {
// Project ID for this request.
project: 'my-project', // TODO: Update placeholder value.
// The name of the zone for this request.
zone: 'my-zone', // TODO: Update placeholder value.
// Name of the instance scoping this request.
instance: 'my-instance', // TODO: Update placeholder value.
resource: {
// TODO: Add desired properties to the request body.
},
auth: authClient,
};
compute.instances.setLabels(request, function(err, response) {
if (err) {
console.error(err);
return;
}
// TODO: Change code below to process the `response` object:
console.log(JSON.stringify(response, null, 2));
});
});
function authorize(callback) {
google.auth.getClient({
scopes: ['https://www.googleapis.com/auth/cloud-platform']
}).then(client => {
callback(client);
}).catch(err => {
console.error('authentication failed: ', err);
});
}
Remember to send the request body as a parameter when writing your code.
Consider the following when using this method:
You will need to specify the current labels your instance has under labelFingerprint.
Your instance's labels will be overwritten, so make sure to include in request body any labels you'd want to keep.

What incorrect Metadata-Flavor header at GoogleAuth means?

I´m trying to write to firestore from a onCall firebase function
functions.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
console.log('initialing functions at ' , new Date().toString())
exports.getLinks = functions.runWith({ timeoutSeconds: 540 }).https.onCall( (data,context) => {
console.log('starting to get links ' , new Date().toString())
console.log('data' , data.query, data.limit, data.country, data.uid)
console.log('context auth', context.auth, 'context.auth.uid', context.auth.uid)
// is there anything like admin.setCredentials(context.auth) necessary here?
const queries = admin.firestore().collection('queries');
let uid = data.uid
console.log('uid', uid);
console.log('queries ref', queries)
//probably when trying to write here is not being allowed
queries.doc(uid).set({LinksArrayLength: 'starting'})
.then( r => console.log('writing to firestore 1 result', r))
.catch( err => console.error('writing to firestore 2 error', err))
The console output is like this
starting to get links Fri May 31 2019 19:01:10 GMT-0300 (GMT-03:00)
data sells anywhere 2 com fwfwqe
context auth {
uid: 'f23oij2ioafOIJOeofiwjOIJ',
token: {
iss: 'https://securetoken.google.com/was98oinr-fa4c9',
aud: 'was234r-f32c9',
auth_time: 1559327744,
user_id: 'f23oij2ioafOIJOeofiwjOIJ',
sub: 'f23oij2ioafOIJOeofiwjOIJ',
iat: 1559338208,
exp: 1559341808,
email: 'awef3h#gmail.com',
email_verified: false,
firebase: { identities: [Object], sign_in_provider: 'password' },
uid: 'f23oij2ioafOIJOeofiwjOIJ'
}
} context.auth.uid f23oij2ioafOIJOeofiwjOIJ
uid f1EMxzwjJlTaH3u7RAYsySx0MZV2
queries ref CollectionReference {
_firestore: Firestore {
_settings: {
projectId: 'xxx',
firebaseVersion: '7.0.0',
libName: 'gccl',
libVersion: '1.3.0 fire/7.0.0'
},
and then the not allowed write request to firestore ?
writing to firestore 2 error Error: Unexpected error determining execution environment: Invalid response from metadata service: incorrect Metadata-Flavor header.
> at GoogleAuth.<anonymous> (H:\nprojetos\whats_app_sender\firebase_sender\vue_sender\wa_sender\functions\node_modules\google-auth-library\build\src\auth\googleauth.js:164:23)
> at Generator.throw (<anonymous>)
> at rejected (H:\nprojetos\whats_app_sender\firebase_sender\vue_sender\wa_sender\functions\node_modules\google-auth-library\build\src\auth\googleauth.js:20:65)
> at processTicksAndRejections (internal/process/task_queues.js:89:5)
How could I ensure that the request.auth.uid is being sent to the firestore write request?
Firestore rules
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;//: if request.auth.uid != null;
// even when commented and allowing all requests still giving the error //message
}
}
}
Even when fully allowed is continues to give the error.
I´m trying to write to firestore to update the client side when something is being written to the the collections('queries') ... so that the client gets notified of the function progress...
Is there is a better way of doing that also?
On the client side the code goes like this
client-side
fireApp.firestore().collection('queries').doc(this.getUser.uid).onSnapshot(snap => {
debugger
console.log('snap', snap)
snap.exists ?
snap.docChanges().forEach(async change => {
if (change.type === "modified") {
_vue.updating = true // the function is in progress
Solved
It just required propper initialization
const credential = require('./xxxxx.json')
admin.initializeApp({credential: admin.credential.cert(credential),
databaseURL: "https://xxx.xxx.firebaseio.com"
});
this link (https://www.youtube.com/watch?v=Z87OZtIYC_0)
explains how to initialize it properly

Resources