@alexanderkhitev
March 4, 2018 12:30 PM
I had a task, after registering users in the application (registering through facebook) to keep facebook avatar in firebase storage, as facebook links have a limited period of work. I implemented the function I'll write below, but I get the following error The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method, when I try to use a link to an image. Please tell me how it can be fixed?
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const gcs = require('@google-cloud/storage')({keyFilename: "service-account-credentials.json"});
const uuid = require('uuid');
const imageDownloader = require('../lib/Images/image-manager.js');
const path = require('path');
const timestamp = require('unix-timestamp');
module.exports = functions.https.onRequest((req, res) => {
const token = req.header('X-Auth-MyApp-Token');
const imageURL = req.body.imagePath;
const bucketName = functions.config().googlecloud.defaultbacketname;
const bucket = gcs.bucket(bucketName);
var userID = '';
const shortID = uuid.v1();
const filename = shortID + '.jpg';
var profileImagePath = '';
return admin.auth().verifyIdToken(token).then(decodedToken => {
userID = decodedToken.uid;
return imageDownloader.downloadImageToLocalDirectory(imageURL, filename)
}).then(localImagePath => {
profileImagePath = path.normalize(path.join('userImages', userID, 'profileImages', filename));
const uploadProm = bucket.upload(localImagePath, {
destination: profileImagePath,
uploadType: "media",
metadata: {
contentType: 'image/jpeg'
}
});
return uploadProm;
}).then(() => {
console.log('success uploaded');
const config = {
action: 'read',
expires: '03-01-2400',
contentType: 'image/jpeg'
};
const userRefPromise = admin.database().ref()
.child('users')
.child(userID)
.once('value');
const profileImageFile = bucket.file(profileImagePath);
return Promise.all([profileImageFile.getSignedUrl(config), userRefPromise])
}).then(results => {
const url = results[0][0];
const userModel = results[1].val();
const userCheckID = userModel['id'];
console.log("get url", url);
// save to database
const userImagesRef = admin.database().ref().child('userImages')
.child(userID)
.child('userProfileImages')
.push();
const timeStamp = timestamp.now();
console.log('timeStamp', timeStamp);
const imageModelID = userImagesRef.key;
const userImagesRefPromise = userImagesRef.update({
'path': url,
'id': imageModelID,
'fileName': filename,
'timeStamp': timeStamp
});
const userRef = admin.database().ref()
.child('users')
.child(userID)
.child('currentProfileImage');
const userRefPromise = userRef.update({
'path': url,
'id': imageModelID,
'fileName': filename,
'timeStamp': timeStamp
});
return Promise.all([userImagesRefPromise, userRefPromise]);
}).then(() => {
const successJSON = {};
successJSON["message"] = "Success operation";
return res.status(200).send(successJSON);
}).catch(error => {
console.log(error);
const errorJSON = {};
errorJSON["error"] = error;
return res.status(error.code).send(errorJSON);
});
});
const config = {
action: 'read',
expires: '03-01-2400',
contentType: 'image/jpeg'
};
If you provide a content-type, the client (browser) must provide this HTTP header set to the same value.
Is that happening?
(related: https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1976)
hi @stephenplusplus I'm sorry I wrote it here. No, this problem does not happen anymore, I solved this problem with the Firebase support team. Thank you
Oh, great to hear! Thanks for letting me know.
@alexanderkhitev I am experiencing the same issue, how did you resolve? Same issue reported in a few places, including here https://github.com/firebase/functions-samples/issues/360 , and here https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1976
My URL works for a few days, and then seems to expire with "SignatureDoesNotMatch" 403 response. So, does not seem to be a matter of including/excluding content-type or using the same request method. The URL just simply ceases to work using the same exact request and conditions.
The relevant query parameter, as an example: '...&Expires=16730323200&Signature=...'
For reference, here is a repo of relevant code:
Same issue here.
I'm having the same problem. My Firebase Storage download URLs fail after three days, saying that the signatures don't match. The expiration dates are good. I don't specify contentType when I upload the files to Storage. When I tried specifying contentType the download URLs immediately failed, with the same error message. Google's documentation says it should be Content_Type, or maybe Content-Type, not contentType.
I have the same issue. I am also not providing a contentType.
I just wrote a long answer on Stack Overflow:
Thomas David Kehoe
LanguageTwo.com
On May 6, 2019 at 10:18 AM Thomas Anderl notifications@github.com wrote:
I have the same issue. I am also not providing a contentType. — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/googleapis/nodejs-storage/issues/144#issuecomment-489680714 , or mute the thread https://github.com/notifications/unsubscribe-auth/ABIJAYYMTAM6JVMJNKXPVZLPUBK4HANCNFSM4ETWEDOQ .
I also had the same issue but I wasn't setting contentType field for the sign url options which perplexed me and I realised in Postman or my client I had to also set Content-Type as nothing, left it blank and it started working!
Most helpful comment
@alexanderkhitev I am experiencing the same issue, how did you resolve? Same issue reported in a few places, including here https://github.com/firebase/functions-samples/issues/360 , and here https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1976
My URL works for a few days, and then seems to expire with "SignatureDoesNotMatch" 403 response. So, does not seem to be a matter of including/excluding content-type or using the same request method. The URL just simply ceases to work using the same exact request and conditions.
The relevant query parameter, as an example: '...&Expires=16730323200&Signature=...'
For reference, here is a repo of relevant code:
https://github.com/colinjstief/getSignedUrl-example