When you delete a file (specifically in this case photos) through Firebase Cloud Functions, some files are deleted well, some remain in Firebase Storage. I get an error in the logs when the files are not deleted, the text of the error.
Error: read ECONNRESET at exports._errnoException (util.js:1026:11) at TCP.onread (net.js:569:26)
Error: read ECONNRESET
at exports._errnoException (util.js:1026:11)
at TCP.onread (net.js:569:26)
My code
var functions = require('firebase-functions');
const admin = require('firebase-admin');
const gcs = require('#google-cloud/storage')();
admin.initializeApp(functions.config().firebase);
// deleting functions
exports.userDidDeleted = functions.auth.user().onDelete(event => {
const user = event.data; // The Firebase user.
const email = user.email; // The email of the user.
const displayName = user.displayName; // The display name of the user.
const userSearchLocationModelPath = '/userSearchLocationModel/' + user.uid;
console.log('userDidDeleted', userSearchLocationModelPath);
admin.database().ref(userSearchLocationModelPath).remove();
// cards
var cardsRef = admin.database().ref('cards')
cardsRef.orderByChild('ownerID').equalTo(user.uid).on("child_added", function(snapshot) {
console.log('cardsRef', snapshot.key, snapshot.val);
const cardRef = '/cards/' + snapshot.key;
admin.database().ref(cardRef).remove();
// location
admin.database().ref('cardLocation').child(snapshot.key).remove();
// photo
const filePath = 'cardImages/' + snapshot.key + '/mainCardPhoto/' + 'main.jpg';
const bucket = gcs.bucket('example-example7.appspot.com');
const file = bucket.file(filePath);
const pr = file.delete();
});
});
After consulting Jen Person I changed the code and it works for me.
// deleting functions
exports.userDidDeleted = functions.auth.user().onDelete(event => {
const user = event.data; // The Firebase user.
const email = user.email; // The email of the user.
const displayName = user.displayName; // The display name of the user.
const userSearchLocationModelPath = '/userSearchLocationModel/' + user.uid;
console.log('userDidDeleted', userSearchLocationModelPath);
admin.database().ref(userSearchLocationModelPath).remove();
// cards
var cardsRef = admin.database().ref('cards')
cardsRef.orderByChild('ownerID').equalTo(user.uid).on("child_added", function(snapshot) {
// there, I queried!
console.log('cardsRef', snapshot.key, snapshot.val);
const cardRef = '/cards/' + snapshot.key;
admin.database().ref(cardRef).remove();
// location
admin.database().ref('cardLocation').child(snapshot.key).remove();
// photo
const firebasestoragePath = 'firebasestorage.googleapis.com';
const placeVenuePhotoPath = '' + snapshot.child('photoURLsProperties').child('placeVenuePhoto').val();
if (placeVenuePhotoPath.includes(firebasestoragePath)) {
const filePath = 'cardImages/' + snapshot.key + '/mainCardPhoto/' + 'main.jpg';
const bucket = gcs.bucket('example-example7.appspot.com');
const file = bucket.file(filePath);
const pr = file.delete();
return console.log(filePath, "is deleted");
} else {
return console.log("card did not have a custom image", snapshot.key);
}
});
Related
I'm trying to call my solana contract from my frontend app.
Even though I added the baseAccount. Solana complains it's not added. Whats going on?
const baseAccount = Keypair.generate()
async function createNFT({ nftPrice, nftRoyalty, nftInfo }) {
// console.log('image', image)
// const added = await client.add(image)
// console.log(
// '`https://ipfs.infura.io/ipfs/${added.path}`',
// `https://ipfs.infura.io/ipfs/${added.path}`
// )
const provider = await getProvider()
const program = new Program(idl, programID, provider)
const price = new BN(nftPrice * 10 ** 9)
const result = await program.rpc.mintNft(
wallet.publicKey,
price,
nftRoyalty,
wallet.publicKey,
nftInfo,
{
accounts: {
baseAccount: baseAccount.publicKey,
user: provider.wallet.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [baseAccount],
}
)
console.log('result', result)
}
Is there some one who can really help here?
I can't get anything from sso.getGraphData in the office addin generated from Yeoman generator.
Here is my code in ssoauthhelper.js:
export async function getGraphData() {
try {
let bootstrapToken = await OfficeRuntime.auth.getAccessToken({ allowSignInPrompt: true });
let exchangeResponse = await sso.getGraphToken(bootstrapToken);
if (exchangeResponse.claims) {
// Microsoft Graph requires an additional form of authentication. Have the Office host
// get a new token using the Claims string, which tells AAD to prompt the user for all
// required forms of authentication.
let mfaBootstrapToken = await OfficeRuntime.auth.getAccessToken({ authChallenge: exchangeResponse.claims });
exchangeResponse = sso.getGraphToken(mfaBootstrapToken);
}
if (exchangeResponse.error) {
// AAD errors are returned to the client with HTTP code 200, so they do not trigger
// the catch block below.
documentHelper.writeDataToOfficeDocument("response");
handleAADErrors(exchangeResponse);
} else {
/*const response = await sso.makeGraphApiCall(exchangeResponse.access_token);
documentHelper.writeDataToOfficeDocument(response);*/
const _EndPoint = "/me/messages";
const _UrlParams = "?$select=receivedDateTime,subject,isRead&$orderby=receivedDateTime&$top=10";
const response = await sso.getGraphData(exchangeResponse.access_token, _EndPoint, _UrlParams);
documentHelper.writeDataToOfficeDocument(response);
sso.showMessage("Your data has been added to the document.");
}
} catch (exception) {
if (exception.code) {
if (sso.handleClientSideErrors(exception)) {
fallbackAuthHelper.dialogFallback();
}
} else {
sso.showMessage("EXCEPTION: " + JSON.stringify(exception));
}
}
}
the code in documentHelper.js:
function writeDataToExcel(result) {
/*return Excel.run(function (context) {
const sheet = context.workbook.worksheets.getActiveWorksheet();
let data = [];
let userProfileInfo = filterUserProfileInfo(result);
for (let i = 0; i < userProfileInfo.length; i++) {
if (userProfileInfo[i] !== null) {
let innerArray = [];
innerArray.push(userProfileInfo[i]);
data.push(innerArray);
}
}
const rangeAddress = `B5:B${5 + (data.length - 1)}`;
const range = sheet.getRange(rangeAddress);
range.values = data;
range.format.autofitColumns();
return context.sync();
});*/
return Excel.run(function (context) {
const sheet = context.workbook.worksheets.getActiveWorksheet();
const rangeHeadings = sheet.getRange("A1:D1");
rangeHeadings.valueTypes = [["ReceivedDateTime", "subject", "Read?", "ID"]];
const _Contents = result.value;
for (let i = 0; i < _Contents.length; i++) {
if (_Contents !== null) {
let _TempArr = [];
_TempArr.push(_Contents[i].receivedDateTime);
_TempArr.push(_Contents[i].subject);
_TempArr.push(_Contents[i].isRead);
_TempArr.push(_Contents[i].id);
let _Data = [];
_Data.push(_TempArr);
const _rangeaddress = `A${2 + i}:D${2 + i}`;
const _rangedata = sheet.getRange(_rangeaddress);
_rangedata.values = _Data;
}
}
rangeHeadings.format.autofitColumns();
return context.sync();
});
}
When i run the add-in, it does not proceed after GET/ auth? as shown in below image.
Here are my permission in the Azure APP Registration:
I can't understand what is really happening. When i click on the button in the sideloaded task pane, nothing is sent from the Graph API as shown in the command prompt image. I am really grateful, if someone could point out where the error is.
I have defined the scopes in my manifiest file as well.
Please help.
I'm trying to update the NativeScript plugin nativescript-local-notifications to display images in the notifications.
That's already working on Android here, but I'm having some issues when trying to implement the same thing for iOS.
I have done some changes to the method schedulePendingNotificationsNew in local-notifications.ios.ts:
private static async schedulePendingNotificationsNew(pending: ScheduleOptions[]): Promise<void> {
...
content.userInfo = userInfoDict; // Not changed
if (options.image) {
const image: ImageSource = await imageSource.fromUrl(options.image);
const imageName: string = options.image.split('/').slice(-1)[0];
const imageExtension: "png" | "jpeg" | "jpg" = <"png" | "jpeg" | "jpg">imageName.split('.')[1]
const folderDest = fileSystemModule.knownFolders.temp();
const pathDest = fileSystemModule.path.join(folderDest.path, imageName);
console.log(`Image will be saved to = ${ pathDest }`);
const saved = image.saveToFile(pathDest, imageExtension);
console.log(`Image ${ saved ? '' : 'not' } saved. `);
console.log(`Image does ${ fileSystemModule.File.exists(pathDest) ? '' : 'not' } exist. `);
if (saved || fileSystemModule.File.exists(pathDest)) {
console.log('Attaching image...');
try {
const attachment = UNNotificationAttachment
.attachmentWithIdentifierURLOptionsError('attachment', NSURL.fileURLWithPath('file://' + pathDest), null);
// .attachmentWithIdentifierURLOptionsError('attachment', NSURL.fileURLWithPath(pathDest), null);
content.attachments = NSArray.arrayWithObject<UNNotificationAttachment>(attachement);
} catch(err) {
console.log('Attachment error ; ', err);
}
console.log('Image attached!');
}
}
const repeats = options.interval !== undefined; // Not changed
...
}
You can see I have created the attachment in two different ways:
const attachment = UNNotificationAttachment
.attachmentWithIdentifierURLOptionsError('attachment',
NSURL.fileURLWithPath('file://' + pathDest), null);
And:
const attachment = UNNotificationAttachment
.attachmentWithIdentifierURLOptionsError('attachment',
NSURL.fileURLWithPath(pathDest), null);
But none of them work, in both cases I get a text-only notification and these logs:
Image will be saved to = /var/mobile/Containers/Data/Application/.../Library/Caches/1974-lancia-stratos-hf-stradale-for-sale.jpg
Image not saved.
Image does not exist.
I'm testing it on an iPhone 7 and an iPhone 8 and the image I'm trying to save is this one: https://icdn-0.motor1.com/images/mgl/7WjgW/s3/1974-lancia-stratos-hf-stradale-for-sale.jpg
I fixed it by forcing the image to be saved as png:
export class LocalNotificationsImpl extends LocalNotificationsCommon implements LocalNotificationsApi {
...
private static guid() {
// Not the best, but will it will do. See https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
return `${ s4() }${ s4() }-${ s4() }-${ s4() }-${ s4() }-${ s4() }${ s4() }${ s4() }`;
}
private static getImageName(imageURL: string = "", extension: "png" | "jpeg" | "jpg" = "png"): [string, string] {
const name: string = imageURL.split(/[\/\.]/).slice(-2, -1)[0] || LocalNotificationsImpl.guid();
return [name, `${ name }.${ extension }`];
}
...
private static async schedulePendingNotificationsNew(pending: ScheduleOptions[]): Promise<void> {
...
const imageURL: string = options.image;
if (imageURL) {
const image: ImageSource = await imageSource.fromUrl(imageURL);
const [imageName, imageNameWithExtension] = LocalNotificationsImpl.getImageName(imageURL, "png");
const path: string = fileSystemModule.path.join(
fileSystemModule.knownFolders.temp().path,
LocalNotificationsImpl.getImageName(imageURL, "png"),
);
const saved = image.saveToFile(path, "png");
if (saved || fileSystemModule.File.exists(path)) {
try {
const attachment = UNNotificationAttachment
.attachmentWithIdentifierURLOptionsError('attachment', NSURL.fileURLWithPath(path), null);
content.attachments = NSArray.arrayWithObject<UNNotificationAttachment>(attachment);
} catch(err) {}
}
}
...
}
}
If you are interested, these changes have been merged to my fork of the plugin and there's a PR open in the official one.
I am trying to send a notification when a number is written to _random. I am able to get the device token, and the cloud function works perfectly. However, I do not receive the notification on the simulator. I am using the notification token that is pushed to Firebase to test with. If anybody can help, it will be highly appreciated.
https://i.stack.imgur.com/OB94c.png
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
//Initial function call:
exports.makeRandomFigures = functions.https.onRequest((req, res) => {
//create database ref
var rootRef = admin.database().ref();
var doc_count_temp = 0;
var keys = [];
var random_num = 0;
//get document count
rootRef.once('value', (snapshot) => {
doc_count_temp = snapshot.numChildren();
//real number of member. if delete _timeStamp then minus 2 not 3!
var doc_count = doc_count_temp - 3;
//get num array previous generated
var xRef = rootRef.child("_usedFigures");
xRef.once('value', function(snap) {
snap.forEach(function(item) {
var itemVal = item.val();
keys.push(itemVal);
});
//get non-duplicated random number
var is_equal = true;
while (is_equal) {
random_num = Math.floor((Math.random() * doc_count) + 1);
is_equal = keys.includes(random_num);
}
//insert new random vaule to _usedFigures collection
rootRef.child('_usedFigures').push(random_num);
rootRef.child('_random').set(random_num);
});
});
//send back response
res.redirect(200);
});
exports.sendFigureNotification = functions.database.ref('_random').onWrite(event => {
const payload = {
notification: {
title: 'Title',
body: `Test`, //use _random to get figure at index key
badge: '1',
sound: 'default'
}
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24, //24 hours
content_available: true
};
const token = "cge0F9rUTLo:APA91bGNF3xXI-5uxrdj8BYqRPkxUPA5x9IQALtm3VEFJAdV2WQrQufNkzIclT5B671mBcvR6IDMbgSKyL7iG2jAuxRM3qR3MXhkNp1_utlXhCpE2VZqTw6Yw3d4iMMvHl1B-Cvik6NY";
console.log('Sending notifications');
return admin.messaging().sendToDevice(token, payload, options);
});
You can't get push notifications on the simulator.
To try some alternative ways check this link :
How can I test Apple Push Notification Service without an iPhone?
const functions = require('firebase-functions');
var IAPVerifier = require('iap_verifier');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.verifyReceipt = functions.database.ref('/Customers/{uid}/updateReceipt')
.onWrite(event => {
const uid = event.params.uid;
var receipt = event.data.val();
(strReceipt).toString('base64');
var client = new IAPVerifier('IAP_secretkey')
client.verifyAutoRenewReceipt(receipt, true,function(valid, msg, data){
console.log(' RECEIPT');
if(valid) {
console.log('VALID RECEIPT');
console.log('msg:' + msg);
var strData = JSON.stringify(data);
console.log('data"' + strData);
const newReceiptRef = admin.database().ref('/Customers/{uid}/');
newReceiptRef.update({'receiptData1': data});
const recVerRef = admin.database().ref('/Customers/{uid}/');
newReceiptRef.update({'updateReceipt': 0});
// update status of payment in your system
}else{
console.log('INVALID RECEIPT');
console.log('msg:' + msg);
var strData = JSON.stringify(data);
console.log('data"' + strData);
}
});
});
This is my node js cloud function. The possible values for 'updateReceipt' are 0 and 1. Is it possible to run the cloud function only when the value is 1?
Thanks.
There is no way to only trigger the function when a specific value is present.
I can think of two options:
Write the nodes to a different branch depending on the updateReceipt value.
Add an if to your code.
The second options is definitely the simplest:
exports.verifyReceipt =
functions.database.ref('/Customers/{uid}/updateReceipt')
.onWrite(event => {
const uid = event.params.uid;
var receipt = event.data.val();
if (receipt.updateReceipt === 0) {
var client = new IAPVerifier('IAP_secretkey')
...
Alternatively, you can keep the updated receipt in a separate branch from the new receipts. That way you can trigger a function separately for just the new receipts.