I am using Amplify CLI for datastore. It is working fine. But it is not syncing data with dynamodb.
Means Post gets save in datastore local storage but does not go in dynamodb POST table. My code is below
const {syncExpression} = require("aws-amplify")
const {Amplify} = require("aws-amplify")
const Post = require("./models")
const awsconfig = require("./aws-exports")
Amplify.configure(awsconfig.awsmobile)
exports.handler = async (event) => {
try {
console.log("inside")
let response=await DataStore.save(
new Post.Post({
title: "My second Post",
status:"DRAFT",
rating: 7
})
);
console.log("Post saved successfully!");
return response;
} catch (error) {
console.log("Error saving post", error);
}
};
It gives the following output:
[WARN] 30:08.206 DataStore - Realtime disabled when in a server-side environment
[WARN] 30:11.411 DataStore - User is unauthorized to query syncPosts with auth mode AWS_IAM. No data could be returned.
Post saved successfully!
Result:
{
"title": "My second Post",
"status": "DRAFT",
"rating": 7,
"id": "0a91a191-a6ee-46ff-9dc6-8cac49498cd9"
}
It says Post is saved but it doesn't show up in dynamodb. Is there any problem with warning?
Related
I'm trying to setup automatic backup of my Firestore using instructions here: https://firebase.google.com/docs/firestore/solutions/schedule-export
I get error:
firestoreExpert
g2o6pmdwatdp
TypeError: Cannot read properties of undefined (reading 'charCodeAt')
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)
Any suggestions to debug this?
I've tried looking for errors in my permissions. E.g. I don't know how to check if the service has access to the specific bucket, although the GCL ran OK.
I've also tried looking for errors in the script.
index.js
const firestore = require('#google-cloud/firestore');
const client = new firestore.v1.FirestoreAdminClient();
// Replace BUCKET_NAME
const bucket = 'gs://EDITEDHERE.appspot.com'
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);
});
};
and package.json
{
"dependencies": {
"#google-cloud/firestore": "^1.3.0"
}
}
I found these great video tutorials
How to schedule firestorm backups and
How To Transfer Firestore Data From One Project To Another
I deployed a Nodejs application on AWS using serverless to receive messages from Whatsapp Cloud API Webhook and store the phone number and message in DynamoDB. However, when I trigger a test message from the Dashboard, no message is received by the application.
In the above image, it says - "successfully tested test message". However, no message was logged in Cloudwatch and no field was created in the table.
Below is my handler.js code.
"use strict";
const serverless = require('serverless-http')
const express = require('express')
const app = express()
const token = process.env.TOKEN
app.get('/webhooks', (req, res) => {
if (
req.query['hub.mode'] == 'subscribe' &&
req.query['hub.verify_token'] == token
) {
res.send(req.query['hub.challenge']);
} else {
res.sendStatus(400);
}
})
module.exports.handler = serverless(app);
const AWS = require('aws-sdk')
const dynamoDb = new AWS.DynamoDB.DocumentClient();
app.post('/webhooks', (req, res) => {
const body = JSON.parse(req.body)
console.log("Received request: ", JSON.stringify(body))
if(body.field !== 'messages'){
// not from the messages webhook so dont process
return res.sendStatus(400)
}
const reviews = body.value.messages.map((message)=>{
const reviewInfo = {
TableName: process.env.REVIEW_TABLE,
Item: {
phonenumber: message.from,
review: message.text.body
}
}
console.log("Saving review!")
return dynamoDb.put(reviewInfo).promise()
})
// return 200 code once all reviews have been written to dynamoDB
return Promise.all(reviews).then((data) => res.sendStatus(200));
})
When I tried to test other fields, the request body was logged in cloud watch.
At first, I thought the issue is with the Application deployed in AWS. So I tried to send a request to the endpoint using Postman. But, it worked properly and the phonenumber and message were added to the Table.
In Meta's Support Website, I see the below
Can this be the reason?
I'm writing a cloud function for my iOS app to watch for any follower changes in my users to notify them when someone follows them. My follower subcollection is within each user data document and I use wildcards to listen to any changes. I've also provided good logging during each step, so it's easy to see where the problem is, however, since I'm rather new to cloud functions, I don't know exactly how I'd fix it.
The cloud function is as follows.
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
let title
let body
let payload
let FCMRegistrationToken_KEY
exports.sendNotificationOnFollowerCreate = functions.firestore
.document('Users/{userID}/Followers/{followerID}')
.onCreate((snapshot, context) => {
if(snapshot.after){
// Get the userId and followerId
const userID = context.params.userID;
const followerID = context.params.followerID;
// Get the data of the follower document
const newData = snapshot.after.data()
const fullName = newData.firstName + " " + newData.lastName
title = 'Someone just followed you'
body = fullName + ' Just followed you right now!\n' + 'username: ' + newData.userName
// Create the notification payload
payload = {
notification: {
title: title,
body: body
}
}
// Get FMC token by fetching the FCMToken Document for the userID above.
admin.firestore().collection('FCMTokens').doc(userID).get().then(doc => {
if(!doc.exists) {
console.log('User not found!');
} else {
// Get the data of the document
const data = doc.data();
console.log(data);
FCMRegistrationToken_KEY = data.token
}
})
.catch(error => {
console.log(error);
})
.finally(() => {
//more code here
// Send the notification
admin.messaging().sendToDevice(FCMRegistrationToken_KEY, payload)
.then(response => {
console.log('Notification sent successfully:', response);
})
.catch(error => {
console.log('Error sending notification:', error);
});
});
}
})
Basically when there's a new follower added, I use the userID from the context parameters to fetch the FCM token I have saved for all my users in a FCMTokens collection. After retrieving the token and creating my payload, I invoke a sendToDevice() call through admin.messaging() but it fails for some reason.
However, it fails right after that giving the following error
{
"textPayload": "Function returned undefined, expected Promise or value",
"insertId": "63c38ba0000e2c35c9c62c1d",
"resource": {
"type": "cloud_function",
"labels": {
"function_name": "sendNotificationOnFollowerCreate",
"region": "us-central1",
"project_id": "fir-eris"
}
},
"timestamp": "2023-01-15T05:14:08.928821Z",
"severity": "WARNING",
"labels": {
"execution_id": "no23uq1mg5a3",
"instance_id": "00c61b117c173e48fc2cb6c3b49f2c059090e49b7252db1b187115bd42a62998c4093f283fe06ba4ec0bf7981f108fcadb527843a8c4b3c77ec1"
},
"logName": "projects/fir-eris/logs/cloudfunctions.googleapis.com%2Fcloud-functions",
"trace": "projects/fir-eris/traces/e0d7dfae3ea1340e1ec101d16defc94b",
"receiveTimestamp": "2023-01-15T05:14:09.204309551Z"
}
I'm thoroughly confused as I really don't have that much experience with cloud functions. Can someone guide me through what's happening and what could be a potential fix for this?
Thank you.
The error that you have mentioned in the question is basically seen when a function does not or has incorrectly a return statement. The code you have for cloud function does not seem to have any return statement which will have a promise return.To make sure Cloud functions knows when your code is done, you need to either return a value from the top-level function (in the case that all work happens synchronously), or return a promise from the top-level function (in the case that some work continues after the closing } of the function).
The sendNotificationOnFollowerCreate might be aborted when the trigger function finishes because it isn't waiting for that promise.
Try adding the return similar to example below:
return DeviceToken.then(result => { const token_id = result.val();
console.log(token_id); const payload = { notification:
{ title: "New Job Request", body: `JobID ` + job_id, tag: collapseKey, } };
return admin.messaging().sendToDevice(token_id, payload)
Also check these following examples with similar implementations:
Each then should return a value firebase cloud function
Send Push notification using Cloud function for firebase
Firebase Cloud function says unreachable
Firebase Cloud push notification not being sent to device
Is there a way to send notification by identifying user rather than
device
I'm using Firebase v9.6.2 in a NextJS project. I would need to read JSON files from Firebase Storage. I've created a Flutter App that does that, and this app stores files in Storage, and now I need to read these files from a web project.
I have a simple page in which I implement the following function:
export async function getStaticProps() {
const revalidate = 3;
const storage = getStorage();
const dataPath = "data/";
const reference = ref(storage, dataPath);
const listResult = await listAll(reference);
let listOfFiles = [];
for (let item of listResult.items) {
if (item.name.endsWith(".json")) {
await storage
.getDownloadURL(skillsPath + item.name)
.then(async (url) => {
let content = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
// the error happens before this line so I comment it out:
// content = await content.json();
listOfFiles.push(content);
})
}
}
console.log(listOfFiles);
return { props: { listOfFiles }, revalidate };
}
listOfFiles is this:
[
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: { body: [PassThrough], disturbed: false, error: null },
[Symbol(Response internals)]: {
url: 'https://firebasestorage.googleapis.com/v0/b/blablablabla...',
status: 403,
statusText: 'Forbidden',
headers: [Headers],
counter: 0
}
},
...
]
Notes:
The issue does not come from the rules
The user is authenticated
I have enabled Firebase Storage and there are my files, I get the correct URL.
Basically it looks like the example on the official documentation here, however it does not work with NextJS (with XMLHttpRequest either: XMLHttpRequest is not defined).
If this problem is too complicated, or impossible, maybe I can use Firestore instead, however my JSON files are pretty big and I don't know if there is a limitation on the size of the data's keys.
I hope this is clear, please tell me if not.
I am attempting to setup Cloud Vision on my local machine in a Firebase project but I am encountering problems with the default credentials.
First, I encountered Could not load the default credentials. This post suggested that I do gcloud auth application-default login. Upon attempting that, I encountered this:
Error: 7 PERMISSION_DENIED: Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the vision.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.
I also attempted exports GOOGLE_APPLICATION_CREDENTIALS = "pathToServiceAccount" but it didn't work in my case.
Note that I have no issue reading/writing data to Firestore and Firebase Storage. The moment my code hits the Cloud Vision part, it throws the error. I have activated the API on cloud console and enabled billing. Security rules in firestore and storage are in testing mode at this moment.
const vision = require('#google-cloud/vision');
var admin = require('firebase-admin');
let serviceAccount = require('../path-to-service-account.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: "mybucket.appspot.com"
});
let db = admin.firestore()
let bucket = admin.storage().bucket();
//Some networking code, return a promise
.then(response => {
//setup storagePath
return pipeToStorage(item, response, storagePath) //Save to firebase storage ok
})
.then((item) => {
return performTextDetection(item.id) //Throws error here
})
function pipeToStorage(item, response, storagePath) {
return new Promise((resolve, reject) => {
gcFile = bucket.file(storagePath)
response.data
.pipe(gcFile.createWriteStream({
metadata : {
contentType: "application/pdf"
}
}))
.on('error', (error) => {
reject(error)
})
.on('finish', () => {
resolve(item)
})
})
}
function performTextDetection(id) {
const client = new vision.ImageAnnotatorClient();
const bucketName = bucket.name;
const fileName = `items/${id}.pdf`
const outputPrefix = 'ocr_results'
const gcsSourceUri = `gs://${bucketName}/${fileName}`;
const gcsDestinationUri = `gs://${bucketName}/${outputPrefix}/${id}/`;
const inputConfig = {
mimeType: 'application/pdf',
gcsSource: {
uri: gcsSourceUri,
},
};
const outputConfig = {
gcsDestination: {
uri: gcsDestinationUri,
},
};
const features = [{type: 'DOCUMENT_TEXT_DETECTION'}];
const request = {
requests: [
{
inputConfig: inputConfig,
features: features,
outputConfig: outputConfig,
},
],
};
return client.asyncBatchAnnotateFiles(request)
.then(([operation]) => {
return operation.promise()
})
.then(([filesResponse]) => {
const resultsUri = filesResponse.responses[0].outputConfig.gcsDestination.uri
return resultsUri
})
}
This happens because you have exports rather than export:
exports GOOGLE_APPLICATION_CREDENTIALS = "pathToServiceAccount"
please try:
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/credentials.json"
note that there are not spaces, see details here. By the way, I have also found the same PERMISSION_DENIED error when export is omitted.
The validation step is executing a REST request with curl:
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d #request.json \
https://vision.googleapis.com/v1/images:annotate
See the complete example here.