Setup AppGyver and Firebase REST API

Thank you so much for the guide! It has been immensely helpful.

Just wondering, you’ve actually saved your credentials as App Var before submitting it to HTTP (Firebase Auth). Is it safe to store the login credentials in plaintext in App Var? (Security-wise).

Also, is there any reason why you don’t recommend using AppGyver’s REST API - and using the HTTP Request logic instead - as this post suggests?

Thanks for your time!

Hi @theandrewsiah

Good question about storing the login credentials in an App Var. Not sure if there is a way around this since even the username and password are stored as variables in the login screen when they are first entered. Maybe clearing them out after a successful login?

For an auto re-login in client-side storage, you only need to store the refresh_token and not the email or password.

Regarding the REST API vs HTTP Request … When I first set this up I was learning AppGyver and for some reason, I couldn’t get the REST API to work. Don’t remember why.

Thanks for the swift reply! Great tip on the clearing them out part, will implement it :smile:

Hey vereggen. Just out of curiosity, is this the error that you encountered with trying to use REST API with firestore?

“”"404. That’s an error.

The requested URL /v1/projects/[my-database]/databases/(default)/group/JrbHtINHAHh4yhDU2wRH was not found on this server. That’s all we know."""

I’m not sure why, but my other project with purely a firestore (without firebase auth) works all fine with the RESTAPI. But this single project I’m working on, which has both firebase auth and firestore docs, I can’t access the firestore docs. :thinking:

Hi @theandrewsiah

There are two database types in Firebase … Could Firestore and Realtime Database.

This secure setup only works with the Firebase Realtime Database

1 Like

hi @vereggen

Do you also have a tutorial like this for using Firebase Messaging?

Hi @jordan_vd_berk … I haven’t done it but here’s a post where someone set up push notifications … Push Notification Tutorial

How are you handling the error response to indicate a failed login?

Hi @mac

For a failed login I just pop-up a message saying failed login and then display the message or error from the HTTP response.

I then clear out the password and focus input on the password screen for the user to retry.

image

1 Like

Hi @vereggen !

Excellent work and tutorial the one you did.

I was doing some testing and I was able to use this authentication method with the Cloud Firestore database.

The difference with the Firebase Realtime Database is that when configuring the “Base”, we must include an “HTTP Header”, in whose KEY and LABEL fields we will put "Authorization ".

To obtain data from the database, first we must configure the GET method, and once we have done that with a “Get record” we will make the request to the Cloud Firestore database, in the “Authorization” we will put a formula concatenating two values ​​" Bearer "+ appVars.firebaseLoginReponse.id_token (depending on the variables in your example)

I was able to test it also in DELETE and POST methods and it works too.

Greetings.

2 Likes

Great addition @arielo! Thanks for making this work with the Cloud Firestore database! Well done :slight_smile:

1 Like

thanks arielo. i was reading through the firebase docs trying to figure out how to do this last night and got pretty discouraged. thanks for the guide :slight_smile:

1 Like

Thanks @vereggen for the guide! Like @arielo, I managed to do this yesterday too in Firestore. :slight_smile: However, I’m stuck on the “Remember me” element of it to keep a user signed in.

I’m not 100% sure on what the logic should be, I’ve stored a token to storage and can retrieve it on opening the log in page and get the user details, but for some reason I can’t save that response to the app variable for current user. Not sure if this is the right approach or what I need to do to log them back in - @arielo, have you figured out how to keep a user signed in with Firestore? Any tips would be much appreciated! :slight_smile:

Hi @Freya

I don’t know if I understood your query correctly.

You mean you can’t save the answer to keep it connected?

Or can’t you save the token to keep it connected?

I understand that the token you should use for the “Remember me” function is the refresh_token. Since the id_token is only valid for as long as it appears in the expires_in, it is 3600 seconds.

Hi @arielo

Thank you for getting back to me. Sorry - I don’t think I explained myself very well.

I can save the token in local storage and retrieve it when the app is reopened and the login page is mounted. Then I can use the token to retrieve the user details from Firestore (Firebase Auth REST API) to check the token is still valid, but for some reason cannot save the details to the app variable (when I try to show response.email in a message, it shows up empty). I think the next step would be to dismiss the initial view assuming a positive check on the auth token.

However, I’m also not 100% sure if these are the steps I should be implementing after retrieving the token as this is the first time I’ve done this. Please could you confirm what the steps for remembering a user should be?

Hi @Freya

Ok, now I think I got it right.

It seems to me that the error is that when “logging in” with the refresh_token, it does not return the data in the same way as when logging in with email and password.

In the case of the login with email and password, it returns this data with this structure:

{
  "localId": "ZY1rJK0eYLg...",
  "email": "[user@example.com]",
  "displayName": "",
  "idToken": "[ID_TOKEN]",
  "registered": true,
  "refreshToken": "[REFRESH_TOKEN]",
  "expiresIn": "3600"
}

But when “logging in” with the refresh_token, it gives us this data and with this structure

{
  "expires_in": "3600",
  "token_type": "Bearer",
  "refresh_token": "[REFRESH_TOKEN]",
  "id_token": "[ID_TOKEN]",
  "user_id": "tRcfmLH7o2XrNELi...",
  "project_id": "1234567890"
}

In the second case, it does not return the email, so you will not be able to get it this way.

The option you mentioned seems valid to me, that is, discard the login page in case of a positive check with the refresh_token.

If you want to continue working on what you were doing, you can try the “Get user data” option.

For this option you would first have to use the refresh_token and then with the new id_token you got use an “HTTP request” to get the user data including email.

As a first step you would have to use an “HTTP request” with the refresh_token as explained by @vereggen in his “STEP 2”.

That way, among other things, you get a new id_token and with that data you create a new json variable with this format:

{"idToken":"[FIREBASE_ID_TOKEN]"}

Then, with a new “HTTP request”, it passes in the “Request body” the variable that you created in the previous step and returns the following information:

{
  "users": [
    {
      "localId": "ZY1rJK0...",
      "email": "user@example.com",
      "emailVerified": false,
      "displayName": "John Doe",
      "providerUserInfo": [
        {
          "providerId": "password",
          "displayName": "John Doe",
          "photoUrl": "http://localhost:8080/img1234567890/photo.png",
          "federatedId": "user@example.com",
          "email": "user@example.com",
          "rawId": "user@example.com",
          "screenName": "user@example.com"
        }
      ],
      "photoUrl": "https://lh5.googleusercontent.com/.../photo.jpg",
      "passwordHash": "...",
      "passwordUpdatedAt": 1.484124177E12,
      "validSince": "1484124177",
      "disabled": false,
      "lastLoginAt": "1484628946000",
      "createdAt": "1484124142000",
      "customAuth": false
    }
  ]
}

In this link you have more information

Hope this can help you.

Greetings.

1 Like

Hi @arielo

Thank you so much for your explanation! This was really helpful and it’s working now :smiley: !!

1 Like

Hi @arielo,

I wondered if you might be able to help with the next step…

Do you know how to limit the data so only the logged in user can see their own data?

I’ve tried to implement it with the rules, Writing conditions for Cloud Firestore Security Rules  |  Firebase but I can’t get it working.

Any tips would be hugely appreciated!

Hi @Freya,

In order to do that, each piece of data would have to be saved using as the main key of the document, the UserID of the user who generated it.

That way, with a rule that allows you to verify that the UserID of the content creator is equal to the UserID of the person who wants to read the content, it would be enough.

The following example rules are given in the Cloud Firestore documentation for the case of allowing a user to write and only read data that they own.

service cloud.firestore {
  match / databases / {database} / documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match / users / {userId} {
      allow read, update, delete: if request.auth! = null && request.auth.uid == userId;
      allow create: if request.auth! = null;
    }
  }
}

In this case, all the information generated by the user is saved in a document with the key “userID” in the “users” collection.

Hope this can help you.

Greetings.

Hi @arielo , thank you so much for your help!

I’d missed that all their user data needed to be saved under a document with their ID in the users collection.

:slight_smile: Thanks!