How to check if the sheet has been removed? - google-sheets-api

I use the following function to read the spreadsheet by ID:
readSpreadsheet = (spreadsheetId) => {
return window.gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: spreadsheetId,
range: this.props.sheetName + '!A:A',
});
};
However when the sheet was moved to trash, it can still be retrieved like normal. I don't want to write data into the removed sheet, so how can I know if the sheet has been removed or not?

I read through the Google Sheets V4 documentation. Looks like they do not have this function available. Since the sheet is saved in Google Drive, I am able to use Google Drive API to check if file has been removed or not.
Some example code as below:
window.gapi.client.load('drive', 'v2').then(() => {
window.gapi.client.drive.files.get(
{ fileId: spreadsheetId }
).then((response) => {
console.log(response);
if (response && response.result && !response.result.explicitlyTrashed) {
this.setState({ spreadsheetId });
}
return true;
});
});

Related

How to recieve file object from google drive in vuejs?

I want to pick files from google drive as a file object. I am working in vuejs and hence used the vue-google-picker. Google picker is actually returning URL, that I am converting to a file. My code to convert to file:
async convertToFile(docs) {
return new Promise(
resolve => {
docs.map(doc => {
if (doc.url) {
gapi.load('client', function () {
gapi.client.load('drive', 'v3', function () {
var file = gapi.client.drive.files.get({ 'fileId': doc.id, 'alt': 'media' });
console.log(file)
file.execute(function (resp) {
console.log(resp)
resolve(resp)
});
});
});
}
});
}
)
}
console.log(file) shows object like this:
While console.log(resp) shows false. If I see the network tab, then I am receiving the base64 object of the file in preview tab.
How to receive that base64 object in code? What is a method of it? I am also open to any alternative method to receive object file from google drive.
You need to await for drive.files.get method
const file = await gapi.client.drive.files.get({ 'fileId': doc.id, 'alt': 'media' });
console.log(file.body) // here will be the data

React Native using firestore updating array

I am working on a mobile chat application to learn how to use cloud services and have been having some difficulty updating my array of maps without overwriting the array. I have tried multiple different ways but I can only either get it so it overwrites the whole array, or does nothing. I was trying to follow the documentation from firebase for NodeJS to append to the array but cannot get it to work. Any tips on what I am doing wrong? (in my code: db = firebase.firestore();)
sendMessage = async e => {
e.preventDefault();
let date = new Date();
const res2 = await db.collection('indivualChats').doc(this.state.chatID).update({
messages: db.FieldValue.arrayUnion({
mid: res.id,
msg: this.state.message,
timeSent: date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear(),
uid: auth.currentUser.uid})
});
this.setState({
message: '',
})
};
cloud data layout
From Doug's answer you can't direct update of a specific index of array. The alternative way is to read the entire document, modify the data in memory and update the field back into the document or based on the document you can use arrayUnion() and arrayRemove() to add and remove elements.
My example:
Data structure:
Codes in nodejs:
async function transaction(db) {
const ref = db.collection('users').doc('john');
try {
await db.runTransaction(async (t) => {
const doc = await t.get(ref)
const newmessage = 'hello world!';
t.update(ref, {
"message": admin.firestore.FieldValue.arrayUnion({
text: newmessage
})
});
t.update(ref, {
'message': admin.firestore.FieldValue.arrayRemove({
text:doc.data().message[0].text
})
})
});
console.log('Transaction success!');
} catch (e) {
console.log('Transaction failure:', e);
}
}
transaction(db);

"Copy" option missing from Safari Desktop Web Share API?

I am trying to implement the Web Share API for some text I want to allow users to copy/share, and it's been successful except for an issue with Safari desktop. I check for navigator.share and if it exists, then only do I open the native share screen, and if it doesn't, I just copy the text straight to clipboard (like on desktop).
Safari desktop DOES support the Web Share API, however it doesn't seem to provide a way to just copy it? You can see in the screenshot it just gives some options for me. Am I missing something? Is there no way to have "Copy" as an option?
const copyURL = copyText => {
if (navigator.share) {
navigator
.share({ text: copyText })
.then(() => {})
.catch(console.error);
} else {
navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
if (result.state === 'granted' || result.state === 'prompt') {
navigator.clipboard.writeText(copyText).then(() => {
setLinkCopied(true);
});
}
});
}
};
There is indeed no "Copy" feature in desktop Safari's share sheet. The good news is that Safari supports the Async Clipboard API, so you can easily use it as an alternative, as shown in the example below:
async function copyPageUrl() {
try {
await navigator.clipboard.writeText(location.href);
console.log('Page URL copied to clipboard');
} catch (err) {
console.error('Failed to copy: ', err);
}
}

Upload images from React Native to LoopBack

I need to upload a selection of images that user picked from CameraRoll to the LoopBack Component Storage. The thing is that the component storage is working fine, because I can upload and download the files through Postman. But, when I try to upload from react native to loopback, it always returns "No file content upload" with http status 400.
I read a lot of people talking about it and tried everything and none worked for me.
First, I am taking the images from the CameraRoll and my images array looks like this:
[
{
exists: 1,
file: "assets-library://asset/asset.JPG?id=3FF3C864-3A1A-4E55-9455-B56896DDBF1F&ext=JPG",
isDirectory: 0,
md5: "428c2e462a606131428ed4b45c695030",
modificationTime: 1535592967.3309255,
size: 153652,
uri: null
}
]
In the example above I just selected one image.
I transformed to Blob, then I got:
[
{
_data: {
blobId: "3FF3C864-3A1A-4E55-9455-B56896DDBF1F",
name: "asset.JPG",
offset: 0,
size: 153652,
type: "image/jpeg"
}
}
]
So I tried a lot of things after this, tried to send the blob itself as the request body, tried to append to a form data and send the form data, but it doesn't matter the way I try, I always get the "No file content upload" response.
I also tried the example from Facebook, didn't work: https://github.com/facebook/react-native/blob/master/Libraries/Network/FormData.js#L28
The way I am trying now:
In my view:
finalizarCadastro = async () => {
let formData = new FormData();
let blobs = [];
for(let i=0;i<this.state.fotos.length;i++){
let response = await fetch(this.state.fotos[i]);
let blob = await response.blob();
blobs.push(blob);
}
formData.append("files", blobs);
this.props.servico.criar(formData);
}
And the function that send to my server:
criar: (servico) => {
this.setState({carregando: true});
axios.post(`${REQUEST_URL}/arquivos/seila/upload`, servico, {headers: {'content-type': 'multipart/form-data'}}).then(() => {
this.setState({carregando: false});
this.props.alertWithType("success", "Sucesso", "Arquivo salvo com sucesso");
}).catch(error => {
this.setState({carregando: false});
console.log(error.response);
this.props.alertWithType("error", "Erro", error.response.data.error.message);
})
}
I found the solution. So the problem was actually not the code itself, the problem was sending multiple files at the same time. To fix everything, I did this:
this.state.fotos.forEach((foto, i) => {
formData.append(`foto${i}`, {
uri: foto,
type: "image/jpg",
name: "foto.jpg"
});
})
this.props.servico.criar(formData);
And my function that sends the request to the server:
criar: (servico) => {
this.setState({carregando: true});
axios.post(`${REQUEST_URL}/arquivos/seila/upload`, servico).then((response) => {
this.setState({carregando: false});
this.props.alertWithType("success", "Sucesso", "Arquivo salvo com sucesso");
}).catch(error => {
this.setState({carregando: false});
this.props.alertWithType("error", "Erro", error.response.data.error.message);
})
},
So you don't need to set the Content-Type header to multipart/form-data and don't need to transform the images to blob, actually you just need the uri of each one, and I think the type and name attributes are opcional.

trigger branch io without open url

I'm trying to implement in my app in react native app which I can trigger the branch without open url when I scan QR.
here I'm register with the branch
componentDidMount() {
this._unsubscribeFromBranch = branch.subscribe(({ error, params }) => {
if (error) {
console.error("Error from Branch: " + error)
return
}
console.log("Branch params: " + JSON.stringify(params));
if (params) {
this.setState({ scan: { ...this.state.scan, glassHash: params.hash } }, () => {
this._getCurrentPosition();
});
}
});
}
when I scan with Qr it run the function onSuccess and I want to trigger this branch.subscribe without openURL. if i openURL it works fine but it's not what i want
onSuccess(e) {
console.log(e);
// here i want to trigger the branch
this.setState({ barcodeText: e.data });
console.log(e);
}
i found on react-native-branch-deep-links docs about BranchEvent but I don't see any example about it.
I found this
new BranchEvent("UserScannedItem", buo).logEvent()
but not sure how to implement my custom event
Jackie from Branch here.
Branch links do function properly and retain the data when they are used with QR scanners, including dynamic query parameters (params appended behind the URL). If a QR code was used to open the app, you can retrieve the session data by using getLatestReferringParams(). Here's a sample code snippet on reading deep link data:
branch.subscribe(({ error, params }) => {
if (error) {
console.error('Error from Branch: ' + error)
return
}
// params will never be null if error is null
})
let lastParams = await branch.getLatestReferringParams() // params from last open
let installParams = await branch.getFirstReferringParams() // params from original install
More information on using getLatestReferringParams to handle link opens: https://docs.branch.io/pages/apps/react-native/#using-getlatestreferringparams-to-handle-link-opens
Regarding custom events, here's a sample class for generating standard and custom events with the Branch SDK: https://github.com/BranchMetrics/react-native-branch-deep-linking/blob/63cfc566ea45a6af0663fc7530c36fdb5dbf75e6/src/BranchEvent.js
If you are still having issues, please send over a screenshot of an example QR code with the associated Branch link directly to support#branch.io and I'd be happy to do some testing!
Best,
Jackie