1
votes

I have created an app in Android Studio and linked it with Firebase Realtime Database. I need to perform 3 verifications:

  1. User enters his phone no. and the no. is checked against my database, if it exists then:

  2. One time PIN generated by Notification service of Firebase and phone verified.

  3. On the next screen user's pin is checked against my database and then finally he gets to the menu screen.

Now, I am confused as to what should I set as my security rules, as authentication is taking place on step 2 so I can't put the rules using 'auth' and without 'auth' the database will be public (as far as I know, please correct me if I am wrong) which is not safe. What can be done?

1

1 Answers

1
votes

Indeed, as you mentioned, at Step 1 there is no authentication. Therefore if you want to "directly" read the Real Time database to check that the phone number exists, you cannot avoid everybody having access to the Real Time Database node under which all the phone numbers are listed.

An other option would be to use a Cloud Function that would be called through HTTPS (as a REST API) and that checks if a given phone number is within the list of authorized phone numbers.

In such a way you can apply some restrictive read access rules to the list of phone numbers since the Clouds Function will access it as Admin. And instead of exposing the list of all phone numbers, you only allow to check that ONE phone number is authorized/or not.

Look at the documentation to read how to create a function that can be triggered through an HTTP request https://firebase.google.com/docs/functions/http-events

Basically you would do something like:

exports.checkPhoneNbr = functions.https.onRequest((req, res) => {
  let phoneNumberToCheck = req.query.phoneNumber;

  return admin.database().ref('/phoneNumbers/' + phoneNumberToCheck).once('value').then(snapshot => {
    if (snapshot.val()) {
       //the phone number exists, do something, i.e. write to another database node or send back a successful HTTP response
      //i.e. res.status(200).send("PhoneNbrExists");
    } else {
       //i.e. res.status(200).send("PhoneNbrDoesNotExist");
    }
   }
}

So:

1/ You call this Function from your Android app (through HTTPS), with the phone number in the QueryString of the function URL

2/ The cloud function checks the phone number exists. If so it can send back a success message (or write in a other node of the RT DB). If not it sends back a failure message.

3/ In the Android app, after receiving the response from the Cloud Function continue (or not) with the next step

Also, have a look at the functions samples, and in particular the HTTP ones, like:

https://github.com/firebase/functions-samples/blob/master/quickstarts/time-server/functions/index.js