3

I am using Firebase Realtime Database to create a simple URL shortener. My goal, right now, is to look at the alias the user picked and check the database to see if it already exists. If the alias exists, the function is returned and the user is asked to create a new alias. If not, the data is added to the DB.

The problem I am running into is that snapshot.exists() always returns true. Even if the alias isn't in the database. I have looked at this question and several other questions, but they are all over two years old and are likely outdated.

My code looks like this:

const dbRef = ref(getDatabase());

function submitData() {
  var linkAlias = document.getElementById("alias").value;
  var linkInput = document.getElementById("text").value;
  var linkAuto = document.getElementById("auto").value;
  console.log(linkAlias)
  get(dbRef, `${linkAlias}`).then(function(snapshot) {
    console.log(linkAlias)
    if (snapshot.exists() == true) {
      console.log(snapshot.val());
      alert("This alias already exists!");
      return;
    } else {
      sendDataToDB(linkAlias, linkInput, linkAuto);
      alert("Success!")
    }
  });
}
Bob Brown
  • 144
  • 16
  • 1
    Look up answers on how to claim usernames - they require the same steps as what you are doing here just the data you store is slightly different. Also, the modular SDK supports passing in paths in pieces, you should use `get(dbRef, 'pairs', linkAlias)` instead. – samthecodingman Nov 25 '21 at 22:06
  • @samthecodingman does this mean I would be using Firebase Auth as well? – Bob Brown Nov 25 '21 at 22:11
  • Firebase Auth is not required, but it does help greatly in allowing someone to come back later and edit their links (typos, domain changes, etc.). It also simplifies moderation controls later especially if someone comes and abuses your shortener for dodgy things - you can terminate all links they created. If you don't want users to log in, you can either leave authentication out (adjusting your security rules appropriately - see this [answer](https://stackoverflow.com/a/68411885/3068190)) or use [anonymous authentication](https://firebase.google.com/docs/auth/web/anonymous-auth) in its place. – samthecodingman Nov 25 '21 at 22:22
  • @samthecodingman thanks for the info! Right now, I would like to leave out Auth as I'm just trying to create a prototype for now. My main goal is to make sure that an alias does not already exist. All of the questions I have looked at are all years old, so I don't think I would be able to use the answers. – Bob Brown Nov 25 '21 at 22:28
  • 1
    "The problem I am running into is that snapshot.exists() always returns true." That seems unexpected, and does not match my experience with the API. Can you: 1) change your code to use a hard-coded value for `linkAlias` that doesn't exist in the database? 2) Show a screenshot that shows that the `linkAlias` value does not exist in your database? 3) Show the `console.log(snapshot.exists())` output for that combination? That sort of [reproduction](http://stackoverflow.com/help/mcve) makes it more likely we can spot the problem, or use your example to try and reproduce it in our own. – Frank van Puffelen Nov 25 '21 at 22:46
  • @FrankvanPuffelen actually I have an update - it seems that `snapshot.exists()` is not applying the path filter to it because when I delete the data inside "pairs" as well as "pairs", the data is submitted successfully. It is only when there is already data that it returns true. – Bob Brown Nov 25 '21 at 22:52
  • Good to hear that you made progress on this @BobBrown I'm not sure if I fully understand the new situation though, but if it is still an issue: a repro based on what I said before would be the best way to move forward. – Frank van Puffelen Nov 25 '21 at 22:54
  • RE: Old answers - A lot of existing answers will still work perfectly fine, although [modernizing the syntax](https://firebase.google.com/docs/web/modular-upgrade) might be needed to make sense of them. RE: The path filter - this would suggest that `linkAlias` is an empty string ("") instead of the value you are expecting as trailing slashes are removed by the SDK. – samthecodingman Nov 25 '21 at 22:56
  • @FrankvanPuffelen For number 3, `true` is printed in the console every time except for when there is no data in the tree. – Bob Brown Nov 25 '21 at 22:58
  • @samthecodingman This doesn't make sense though, because I just printed the linkAlias variable and it returned what I had entered in the input box. – Bob Brown Nov 25 '21 at 23:00

1 Answers1

0

In my opinion, after trying to solve this problem for weeks, it may be better to use the Object that my code thinks is the snapshot of just the single alias. Instead, it is a Dict of all the aliases and their URLs.

For example, I can define my Snapshot value:

var codeData = snapshot.val();

And then I can search for the alias in the dictionary keys or values:

if (Object.keys(codeData).includes(linkAlias) === true) {
  ...

I'm going to go with this answer because nothing else has worked for me.

Bob Brown
  • 144
  • 16