[SOLVED] Btoa depricated, New syntax for getting base 64

So the file path and hash keeps coming back undefined when logging for the item metadata. vstudio is telling me that the old syntax is now depricated and I noticed in a later totorial filip uses the tostring method over the btoa. how can I implement this new synatx?

the older method (from the clone rarible in 24 hours tutorial)


and this is the more recent method ive seen(bulk upload tutorial)

const serverUrl = "https://5afgk9nae19l.usemoralis.com:2053/server";
const appId = "lhSPMJb08k6pB25ESY87s7VxvnNZobzHLWHbs8yj";
Moralis.start({ serverUrl, appId });
async function login() {
  hideElement(createItemForm);
  let user = Moralis.User.current();
  if (!user) {
    user = await Moralis.authenticate({ signingMessage: "Log in using Moralis" })
    .then(function (user) {
      console.log("logged in user:", user);
      console.log(user.get("ethAddress"));
    })
    .catch(function (error) {
      console(error);
    });
    initUser();
  }
}

initUser = async () => {
  if (await Moralis.User.current())
  {
    hideElement(userConnectButton);
    showElement(userProfileButton);
    showElement(openCreateItemButton);
  }
  else
  {
    showElement(userConnectButton);
    hideElement(userProfileButton);
    hideElement(openCreateItemButton);
  } 
}

initUser();

logOut = async ()  =>{
  await Moralis.User.logOut();
  hideElement(userInfo);
  initUser();
}

openUserInfo = async () => {
  user = await Moralis.User.current();
  if (user)
  {
    const email = user.get('email');
    if(email){
      userEmailField.value = email;
    }else{
      userUsernameField.value = "";
    }
    userUsernameField.value = user.get('username');
    
    const userAvatar = user.get('avatar');
    if(userAvatar){
      userAvatarImg.src = userAvatar.url();
      showElement(userAvatarImg)
    } else{
      hideElement(userAvatarImg);
    }
    showElement(userInfo);
  }
  else
  {
    login();
  }
}

saveUserInfo = async () => {
  user.set('email', userEmailField.value);
  user.set('username', userUsernameField.value);
  
  if (userAvatarFile.files.length > 0){
    // Moralis can handle any kind of file but her we specify jpegS
    const avatar = new Moralis.File("avatar.jpg", userAvatarFile.files[0]);
    //dont worry about name colisions theyr given names and track by element Id
    user.set('avatar', avatar);
  }
  await user.save();
  alert("We got your info stored!");
  openUserInfo();
}

createItem = async () => {
  if (createItemFile.files.length == 0){
    alert("Are you gonna select a file?");
    return;
  } else if (createItemFile.value.length == 0){
    alert("You need to give he file a name!");
    return;
  }

  const nftFile = new Moralis.File("nftFile.mp4",createItemFile.files[0]);
  await nftFile.saveIPFS();
  
  const nftFilePath = nftFile.ipfs();
  const nftFileHash = nftFile.hash();

  const metadata = {
    name: createItemNameField.value,
    description: createItemDescriptionField.value,
    nftFilePath: nftFilePath,
    nftFileHash: nftFileHash
  };

  const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(metadata))});
  await nftFileMetadataFile.saveIPFS();

  const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
  const nftFileMetadataFileHash = nftFileMetadataFile.hash();
  
  const Item = Moralis.Object.extend("Item");
  //create new instance of the class
  const item = new Item();
  item.set(`name`, createItemNameField.value);
  item.set(`description`, createItemDescriptionField.value);
  item.set(`nftFilePath`, nftFilePath.value);
  item.set(`nftFileHash`, nftFileHash.value);
  item.set(`nftFileMetadataFilePath`, nftFileMetadataFilePath.value);
  item.set(`MetadataFileHash`, nftFileMetadataFileHash.value);
  await item.save();
  console.log(item);
}


hideElement = (element) => element.style.display = "none";
showElement = (element) => element.style.display = "block";

//NavBar
const userConnectButton = document.getElementById("btnConnect");
userConnectButton.onclick = login;

const openCreateItemButton = document.getElementById("btnOpenCreateItem");
openCreateItemButton.onclick = () => showElement(createItemForm);

//User Profile
const userProfileButton = document.getElementById("btnUserInfo");
userProfileButton.onclick = openUserInfo;

const userInfo = document.getElementById("userInfo");
const userUsernameField = document.getElementById("txtUsername");
const userEmailField = document.getElementById("txtEmail");
const userAvatarImg = document.getElementById("imgAvater");
const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);
document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;
document.getElementById("btnLogout").onclick = logOut;

//Item Creation
const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");
const createItemDescriptionField = document.getElementById("txtCreateItemDescription");
const createItemPriceField = document.getElementById("numberCreateItemPrice");
const createItemStatusField = document.getElementById("selectCreateItemStatus");
const createItemFile = document.getElementById("fileCreateItemFile");
document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);
document.getElementById("btnCreateItem").onclick = createItem;


I don’t think that is the same thing what is in those 2 print screens. In one it converts the data to base64 and in another one to hex.

When you upload data to IPFS, if you have the data in a variable, you will have to convert it to json and after that to base64. Even if it says that it is deprecated, maybe it works fine.

what is the problem that you have?

Yes i realize that now after doing some research i had them confused. Hex is base 16 and base 64 is an encoding process that breaks down 3 conescutive bytes into a 6 digit code. Ok i still need to convert it ti base 64 befor i upload it to ipfs right? Surely there is another way using toString right?

there are multiple ways to convert data to base64, you can do your own function if you want too, this is what btoa does:
const btoa = function(str){ return Buffer.from(str).toString('base64'); }

so i was getting an error about buffer beinfg undefined and apparently it was taken out of the library in the last update(node.js) so anyway (hours later) I got this to work to encode the meta data

const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: Buffer.from('metadata').toString('base64')});

if i console log the meta dat after the encode i get the hash but if i console log the item being returned from moralis i get nothing
image

const serverUrl = "https://5afgk9nae19l.usemoralis.com:2053/server";
const appId = "lhSPMJb08k6pB25ESY87s7VxvnNZobzHLWHbs8yj";
Moralis.start({ serverUrl, appId });

var Buffer = require('buffer/').Buffer  // note: the trailing slash is important!

async function login() {
  hideElement(createItemForm);
  let user = Moralis.User.current();
  if (!user) {
    user = await Moralis.authenticate({ signingMessage: "Log in using Moralis" })
    .then(function (user) {
      console.log("logged in user:", user);
      console.log(user.get("ethAddress"));
    })
    .catch(function (error) {
      console(error);
    });
    initUser();
  }
}

initUser = async () => {
  if (await Moralis.User.current())
  {
    hideElement(userConnectButton);
    showElement(userProfileButton);
    showElement(openCreateItemButton);
  }
  else
  {
    showElement(userConnectButton);
    hideElement(userProfileButton);
    hideElement(openCreateItemButton);
  } 
}

initUser();

logOut = async ()  =>{
  await Moralis.User.logOut();
  hideElement(userInfo);
  initUser();
}

openUserInfo = async () => {
  user = await Moralis.User.current();
  if (user)
  {
    const email = user.get('email');
    if(email){
      userEmailField.value = email;
    }else{
      userUsernameField.value = "";
    }
    userUsernameField.value = user.get('username');
    
    const userAvatar = user.get('avatar');
    if(userAvatar){
      userAvatarImg.src = userAvatar.url();
      showElement(userAvatarImg)
    } else{
      hideElement(userAvatarImg);
    }
    showElement(userInfo);
  }
  else
  {
    login();
  }
}

saveUserInfo = async () => {
  user.set('email', userEmailField.value);
  user.set('username', userUsernameField.value);
  
  if (userAvatarFile.files.length > 0){
    // Moralis can handle any kind of file but her we specify jpegS
    const avatar = new Moralis.File("avatar.jpg", userAvatarFile.files[0]);
    //dont worry about name colisions theyr given names and track by element Id
    user.set('avatar', avatar);
  }
  await user.save();
  alert("We got your info stored!");
  openUserInfo();
}

createItem = async () => {
  if (createItemFile.files.length == 0){
    alert("Are you gonna select a file?");
    return;
  } else if (createItemNameField.value.length == 0){
    alert("You need to give he file a name!");
    return;
  }

  const nftFile = new Moralis.File("nftFile.mp4",createItemFile.files[0]);
  await nftFile.saveIPFS();
  
  const nftFilePath = nftFile.ipfs();
  const nftFileHash = nftFile.hash();

  const metadata = {
    name: createItemNameField.value,
    description: createItemDescriptionField.value,
    nftFilePath: nftFilePath,
    nftFileHash: nftFileHash
  };
  
  const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: Buffer.from('metadata').toString('base64')});
  console.log (metadata);
  await nftFileMetadataFile.saveIPFS();

  const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
  const nftFileMetadataFileHash = nftFileMetadataFile.hash();
  
  const Item = Moralis.Object.extend("Item");
  //create new instance of the class
  const item = new Item();
  item.set('name', createItemNameField.value);
  item.set('description', createItemDescriptionField.value);
  item.set('nftFilePath', nftFilePath.value);
  item.set('nftFileHash', nftFileHash.value);
  item.set('nftFileMetadataFilePath', nftFileMetadataFilePath.value);
  item.set('MetadataFileHash', nftFileMetadataFileHash.value);
  await item.save();
  console.log(item);
}

You may want to convert metadata to json and not using metadata sting there

ok so using this now

 const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: Buffer.from('metadata').toJSON('base64')});

and getting
TypeError: Cannot create a Parse.File with that data.

Not there to json, you metadata to be in a string.

still same error

  var buf = Buffer.from(JSON.stringify(metadata));

  const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: JSON.parse(buf)});

Try first to create a valid base64 output, you can protect it with console.log

i did and i get the output when i console log


nftfile Hash
and nftfile Path work
also the hash links work as well so its not the parse its somewhere in the upload and retrival

var buf = Buffer.from(JSON.stringify(metadata));
  const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: buf});```

this dosnet work either and its the same error. Why cant this data be parsed?

an example for a cloud function:

const btoa = function(str){ return Buffer.from(str).toString('base64'); }

Moralis.Cloud.define("upload_function", async (request) => {
  const object = {"key" : "value"}
  const file = new Moralis.File("file_2.json", {base64 : btoa(JSON.stringify(object))});
  x = await file.save({useMasterKey:true});
  console.log(JSON.stringify(x))
  return x;            
});

still the same error Cannot create a Parse.File with that data.

can u explain the code? Ive been testing it for hours and so far this is what i have for the cloud function

 Moralis.Cloud.define("upload_function", async (request) => {
  const object = {"key" : "value"}
  const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(object))});
  x = await nftFileMetadataFile.save({useMasterKey:true});
  console.log(JSON.stringify(x))
  return x;            
});

idk if im calling it correctly

const serverUrl = "https://5afgk9nae19l.usemoralis.com:2053/server";
const appId = "lhSPMJb08k6pB25ESY87s7VxvnNZobzHLWHbs8yj";
Moralis.start({ serverUrl, appId });


async function login() {
  hideElement(createItemForm);
  let user = Moralis.User.current();
  if (!user) {
    user = await Moralis.authenticate({ signingMessage: "Log in using Moralis" })
    .then(function (user) {
      console.log("logged in user:", user);
      console.log(user.get("ethAddress"));
    })
    .catch(function (error) {
      console(error);
    });
    initUser();
  }
}

initUser = async () => {
  if (await Moralis.User.current())
  {
    hideElement(userConnectButton);
    showElement(userProfileButton);
    showElement(openCreateItemButton);
  }
  else
  {
    showElement(userConnectButton);
    hideElement(userProfileButton);
    hideElement(openCreateItemButton);
  } 
}

initUser();

logOut = async ()  =>{
  await Moralis.User.logOut();
  hideElement(userInfo);
  initUser();
}

openUserInfo = async () => {
  user = await Moralis.User.current();
  if (user)
  {
    const email = user.get('email');
    if(email){
      userEmailField.value = email;
    }else{
      userUsernameField.value = "";
    }
    userUsernameField.value = user.get('username');
    
    const userAvatar = user.get('avatar');
    if(userAvatar){
      userAvatarImg.src = userAvatar.url();
      showElement(userAvatarImg)
    } else{
      hideElement(userAvatarImg);
    }
    showElement(userInfo);
  }
  else
  {
    login();
  }
}

saveUserInfo = async () => {
  user.set('email', userEmailField.value);
  user.set('username', userUsernameField.value);
  
  if (userAvatarFile.files.length > 0){
    // Moralis can handle any kind of file but her we specify jpegS
    const avatar = new Moralis.File("avatar.jpg", userAvatarFile.files[0]);
    //dont worry about name colisions theyr given names and track by element Id
    user.set('avatar', avatar);
  }
  await user.save();
  alert("We got your info stored!");
  openUserInfo();
}

createItem = async () => {
  if (createItemFile.files.length == 0){
    alert("Are you gonna select a file?");
    return;
  } else if (createItemNameField.value.length == 0){
    alert("You need to give the file a name!");
    return;
  }

  const nftFile = new Moralis.File("nftFile.mp4",createItemFile.files[0]);
  await nftFile.saveIPFS();
  
  const nftFilePath = nftFile.ipfs();
  const nftFileHash = nftFile.hash();

  const metadata = {
    name: createItemNameField.value,
    description: createItemDescriptionField.value,
    nftFilePath: nftFilePath,
    nftFileHash: nftFileHash
  };
  
  
  
  // const nftFileMetadataFile = new Moralis.File("metadata.json", {base64: Buffer.from('metadata').toString('base64')});
  async function upload_function(){
    const cloudFile = await Moralis.Cloud.run("upload_function");
    const nftFileMetadataFile = new Moralis.File("metadata.json", { base64: cloudFile });
    console.log(nftFileMetadataFile);
  }
  
  upload_function();
  await nftFileMetadataFile.saveIPFS();
  
  const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
  const nftFileMetadataFileHash = nftFileMetadataFile.hash();
  
  const Item = Moralis.Object.extend("Item");
  //create new instance of the class
  const item = new Item();
  item.set('name', createItemNameField.value);
  item.set('description', createItemDescriptionField.value);
  item.set('nftFilePath', nftFilePath.value);
  item.set('nftFileHash', nftFileHash.value);
  item.set('nftFileMetadataFilePath', nftFileMetadataFilePath.value);
  item.set('MetadataFileHash', nftFileMetadataFileHash.value);
  await item.save();
  // console.log(item);
}


hideElement = (element) => element.style.display = "none";
showElement = (element) => element.style.display = "block";

//NavBar
const userConnectButton = document.getElementById("btnConnect");
userConnectButton.onclick = login;
 
const openCreateItemButton = document.getElementById("btnOpenCreateItem");
openCreateItemButton.onclick = () => showElement(createItemForm);

//User Profile
const userProfileButton = document.getElementById("btnUserInfo");
userProfileButton.onclick = openUserInfo;

const userInfo = document.getElementById("userInfo");
const userUsernameField = document.getElementById("txtUsername");
const userEmailField = document.getElementById("txtEmail");
const userAvatarImg = document.getElementById("imgAvater");
const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);
document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;
document.getElementById("btnLogout").onclick = logOut;

//Item Creation
const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");
const createItemDescriptionField = document.getElementById("txtCreateItemDescription");
const createItemPriceField = document.getElementById("numberCreateItemPrice");
const createItemStatusField = document.getElementById("selectCreateItemStatus");
const createItemFile = document.getElementById("fileCreateItemFile");
document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);
document.getElementById("btnCreateItem").onclick = createItem;


I see that you have this code directly in your main.js, this is not going to work when the blowser loads the window

where do you call that cloud function in your code?

you also have to add that btoa function in cloud as it is not accessible by default

You can clearly see where I called the function upload_function in the code above. So before I use btoa as a cloud function I need to add a prototype like I would with a header file for a library? Do you have any good study resources on cloud functions? the short video on cloud functions didnt observe this kind of case. I dont really know where to start and I thought my issue was with the way Im parsing the metadata. This is my first time working with cloud functions and I have no Idea what to do. Im very literate and can solve the issue myself but you know that as a dev half the battle is just finding the right resources. The moralis docs dont aknowledge this particular issue and its been 3 days now on this 1 problem so obviously the issue is my own understanding. This back and forth isnt helping me. I spent the entire day yesterday studying JSON and now im going to spend today researching cloud functions, Surely there is an example of someone using a cloud function like this?

one problem is that .saveIPFS is not yet available in cloud functions

you can test this from normal code, after you authenticate:

const btoa2 = function(str){ return Buffer.from(str).toString('base64'); }

  const object = {"key" : "value"}
  const file = new Moralis.File("file_2.json", {base64 : btoa2(JSON.stringify(object))});
  x = await file.save();
  console.log(JSON.stringify(x))

I think the problrem is 2 assumptions are being made her. You are assuming that I understand how a cloud function works and Im assuming that everything that I was told in the tutorial by you guys is everything that I need to know about them. Clearly both assumptions are wrong. I didnt use saveIPFS in the cloud function, its in the create items function

the above code is not for a cloud function, is for normal web browser javascript code

And how do i use that object in the function? My experience is in bash, C, and a bit of html css and js. I dont kmow how to use that