SUPABASE/JavsScript: how to DELETE user metadata? - javascript

Is there a way to delete user metadata in Supabase? They offer update() option, but it seems it works as patch request, so I can't find a way to delete it.
Here's their code:
```const { user, error } = await supabase.auth.update({
data: { hello: 'world' }
});```
I tried to do this:
```const { user, error } = await supabase.auth.update({
data: {}
});```
But is doesn't do anything.
Can metadata be deleted?
Thanks

It is possible to set the metadata field to an empty JSON object (i.e. {}) but, currently, there is no way to set it to NULL. Also, you would need to know all the fields that are already stored in the metadata because you need to remove each one explicitly.
If this works for your scenario, the way to do it is to send a data object where each field that you want removed has a value of null.
For example, if you have the following JSON in your metadata: { 'field1': 2, 'field2': 'something' }, you can set the metadata to an empty JSON object like this:
supabase.auth.update({ 'data': { 'field1': null, 'field2': null } });

Related

Vue and Javascript API/Object/Array manipulation for searching values

Edit to clarify:I have an object from an API response that I get using the mounted function, data is saved not displayed yet. I need to be able to filter that data by allowing a user to input text in an input box before showing it on the page, then find where that keyword was used in a specific key value(name). Then show the results on a page but include other key/value pairs from the api array. This is what the api response looks like:
class: (...)
facets: (...)
numberFound: (...)
results: Array(202)
[0 … 99]
0:
class: "SearchResult"
contentGuid: "7f19462f-6c25-43a9-bdb5-479f5f42fbde"
dateUpdated: "2018-03-27T16:46:31Z"
description: "Converting a Word Document to Adobe Acrobat PDF Learning Services Converting a Word Document to Adobe Acrobat PDF Enterprise Converting a Word Document to Adobe Acrobat PDF / Reference ..."
document: Object
documentGuid: "035f5c69-d406-4c16-86ca-de12773a0963"
documentId: 154424
documentVersionId: 44043
fileId: 74213
format: "PDF"
id: "Document#1#44043"
isFavorite: false
languages: "English"
name: "Converting a Word Document to Adobe Acrobat PDF"
numberOfIndexedCoobs: 0
numberOfSharedLinks: 1
packageType: "PDF"
previewId: 74213
publicLinkTokens: Array(1)
resourceType: "Other"
score: 0.0054571675
snippets: Object
updatedById: 994
updatedByName: "Michael"
versionName: "3"
For example if someone enters "Adobe" in the search box, I would need to search for the word "adobe" in the name value for the entire object, and only show the ones that have "abobe" somewhere in the name value.
My thought was to get the document name split it, then do an includes() to check for the search term. This works but I can't seem to figure out how to get it all to work together and get the results on the screen, plus get additional information, such as document Id from the original results. this is what I have so far:
async getResults() {
return axios
.get(this.url, {
headers: {
"Content-Type": "application/json",
"Bravais-prod-us-Context": this.getCookie(),
},
})
.then((res) => {
this.search = res.data;
this.search.results.forEach((doc) => {
this.results = doc.document.name
.toLowerCase()
.split(" ")
.includes(this.termSearch.toLowerCase());
console.log(doc.document.name.split(" "));
console.log(this.results);
});
})
.catch((error) => console.log(error));
},
I need to show the original title(some words and acronyms are capitalized) plus the doc id(for url links) and a description, all of this info is in the initial api response.
<div v-for="" v-bind:key="">
{{ ???? }}
</div>
That works in the console but how do I get this back together and on the screen?? Any help is appreciated, not looking for someone else to do my coding, just need some advice.
I would start by diving your logic. At the moment you have a single function that makes an api call and then searches through the results. It would be better suited to have the api call in a separate method so that if the user searches multiple times it doesn't call the api each time. We can easily solve this by adding an extra method that checks if the results object is populated and decides which methods to call.
Casting all strings to lowercase is a good idea to normalize the data. There might be other ways but this works for it's intended purpose. However, splitting a string is unecessary as the includes() method searches through the whole string. See the MDN docs for String.prototype.includes()
To search within an array you can use the filter() method, which will create a new array with all elements that pass the implemented test. See the MDN docs for Array.prototype.filter().
With this in hand, we can write our logic as:
async handleSearch(searchString) {
if (!this.results.length) {
this.getResults()
}
this.searchResults(searchString)
},
async getResults() {
return axios.get(this.url, {
headers: {
"Content-Type": "application/json",
"Bravais-prod-us-Context": this.getCookie(),
},
}).then((res) => {
this.results = res.data.results
}).catch((error) => console.error(error));
},
searchResults(searchString) {
this.filteredResults = this.results.filter(item => {
let name = item.name.toLowerCase();
let searchTerm = searchString.toLowerCase();
return this.name.includes(searchTerm)
})
}
Your input field will call the handleSearch() method, and then you can write you html as such:
<div v-for="result in filteredResults" :key="result.id">
<p>Name: {{result.name}}</p>
<p>Description: {{result.description}}</p>
</div>

Edit readonly javascript objects

I have a read-only object that is returned by GraphQL (vue-apollo) query, the result which is read-only looks something like this:
result: {
id: 'yh383hjjf',
regulations: [{ title: 'Test', approved: false}]
})
I want to bind this to a form and be able to edit/update the values in the regulations array and save it back to the database.
at the moment when I try to edit I get the error below:
Uncaught TypeError: "title" is read-only
I tried cloning the result returned by the database using object.assign
//target template
const regulatoryApprovals = {
id: null,
regulations: [{ title: null, approved: null}]
})
regulatoryApprovals = Object.assign(regulatoryApprovals, result, {
regulations: Object.assign(regulatoryApprovals.regulations, result.regulations)
})
but this didn't work.
Does anyone know how I can properly clone the result?
regulatoryApprovals= Object.assign(regulatoryApprovals, ... indicates the problem because regulatoryApprovals is modified with Object.assign, so it would need no assignment.
Read-only regulatoryApprovals object needs to be cloned. regulations is an array and won't be merged correctly with Object.assign, unless it's known that array elements need to be replaced. It should be:
regulatoryApprovals = {
...regulatoryApprovals,
...result,
regulations: [...regulatoryApprovals.regulations, result.regulations]
}
Where { ...regulatoryApprovals, ... } is a shortcut for Object.assign({}, regulatoryApprovals, ...).

Associating xxxx_id with xxxx.id

I am running into a problem where when I submit a "property listing" I get this response:
{"owner_id":"Batman","address":"test","state":"test","sale_price":"test"}
The thing is "owner_id" is supposed to equal or associate with owner's id in a different table/JSON file (e.g owner_id = owner.id), not a string in this case which is why the object is not saving on the back-end.
Is anyone in vanilla JavaScript able to show me an example on how to associate owner_id and owner.id?
It'd be more like :
{
owner: {
id: "Batman"
},
address: "test",
state: "test",
sale_price: "test"
}
You should take a look at : https://www.w3schools.com/js/js_json_objects.asp
EDIT: Not sure how you're fetching this data but it seems like you want to handle the response you're getting.
Here is a simple GET request using the fetch api:
fetch('http://example.com/heroes') //this is the path to your source where you're getting your response data
.then((response) => {
return response.json();
//above you return a promise containing your response data
//you can also handle your response before declaring it in a var here
})
.then((myJson) => {
//you have stored your response data as a var myJson
console.log(myJson);
//here you can work your response data in any way you need
// to show an example (not that you would do this) I've provided a owner object that checks if it's property is equal to the incoming data
var owner = {
"id": Batman,
}
if ( myJson.owner_id === owner.id ) {
//do something here
}
});
More info here.

Function getting firebase object returns hard to use object

What I am trying to do
I am creating a social media app with react native and firebase. I am trying to call a function, and have that function return a list of posts from off of my server.
Problem
Using the return method on a firebase query gives me a hard to use object array:
Array [
Object {
"-L2mDBZ6gqY6ANJD6rg1": Object {
//...
},
},
]
I don't like how there is an object inside of an object, and the whole thing is very hard to work with. I created a list inside my app and named it items, and when pushing all of the values to that, I got a much easier to work with object:
Array [
Object {
//...
"key": "-L2mDBZ6gqY6ANJD6rg1",
},
]
This object is also a lot nicer to use because the key is not the name of the object, but inside of it.
I would just return the array I made, but that returns as undefined.
My question
In a function, how can I return an array I created using a firebase query? (to get the objects of an array)
My Code
runQ(group){
var items = [];
//I am returning the entire firebase query...
return firebase.database().ref('posts/'+group).orderByKey().once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
//post contents
});
});
console.log(items)
//... but all I want to return is the items array. This returns undefined though.
})
}
Please let me know if I'm getting your question correctly. So, the posts table in database looks like this right now:
And you want to return these posts in this manner:
[
{
"key": "-L1ELDwqJqm17iBI4UZu",
"message": "post 1"
},
{
"key": "-L1ELOuuf9hOdydnI3HU",
"message": "post 2"
},
{
"key": "-L1ELqFi7X9lm6ssOd5d",
"message": "post 3"
},
{
"key": "-L1EMH-Co64-RAQ1-AvU",
"message": "post 4"
}
...
]
Is this correct? If so, here's what you're suppose to do:
var items = [];
firebase.database().ref('posts').orderByKey().once('value', (snapshot) => {
snapshot.forEach((child) => {
// 'key' might not be a part of the post, if you do want to
// include the key as well, then use this code instead
//
// const post = child.val();
// const key = child.key;
// items.push({ ...post, key });
//
// Otherwise, the following line is enough
items.push(child.val());
});
// Then, do something with the 'items' array here
})
.catch(() => { });
Off the topics here: I see that you're using firebase.database().... to fetch posts from the database, are you using cloud functions or you're fetching those posts in your App, using users' devices to do so? If it's the latter, you probably would rather use cloud functions and pagination to fetch posts, mainly because of 2 reasons:
There might be too many posts to fetch at one time
This causes security issues, because you're allowing every device to connect to your database (you'd have to come up with real good security rules to keep your database safe)

firebase $add() .push() .set()

I am using firebase, and angularfire.
there are so many ways to do CRUD with the Firebase Api
actually, I still don't get what is specific difference for using
$add with $firebaseArray
.push() method
.set() method
I think they are technically same, I prefer to use .set method() without knowing the exact reason, why I'd using that. is there any specific reason to not use it? what is exactly $firebaseArray did? if we could just declare basic reference variable.
in this case:
var usersRef = Ref.child('users');
$scope.createUser = function() {
$scope.userRef.child($id).set({
name: name
});
};
or
$scope.data = $firebaseArray(Ref.child('users'));
$scope.createUser = function() {
$scope.data.child($id).$add({
name: name
});
};
thank you.
If I have the following data tree in Firebase:
{
users:
{
key: { name:"bob" }
}
}
When I do an $add, I will create a new item in the tree
$scope.data.child('users').$add({
name: name
});
Since $add uses the Push method in Firebase, new random Key will be used when pushing data to the child.
{
users:
{[
key: { name:"bob" },
key2: { name:"name" }
]}
}
If I do a set on the same Users object, I will overwrite the data that is already there. So, in your example, without specifying a key, you will overwrite the entire user object.
$scope.userRef.child('users').set({
name: name
});
};
This will result with this data
{
users:
{
name: "name"
}
}
This happens because any null values you pass to the Set method will delete any data that was originally there.
Passing null to set() will remove the data at the specified location.
https://www.firebase.com/docs/web/api/firebase/set.html

Categories