Open RICK0707 opened 7 years ago
+1 for authentication with Firebase using password-based accounts
You may find it here http://stackoverflow.com/questions/37418372/firebase-where-is-my-account-secret-in-the-new-console
However, please develop this feature as database secret support is deprecated
Hi, i have same issue. I can't use token to connect firebase database... Can i help me?
Have you any plans to implement Token based Auth ? The issue is open from Last 2.5 Months 👎
Sorry for the late follow-up
It seems that the REST API only support OAuth2.0 based auth, see https://firebase.google.com/docs/reference/rest/database/user-auth
In order to support it in the library we would need to:
?auth=
with ?access_token
client_id
, client_secret
in the sketchaccess_token/refresh_token
pairrefresh_token
in the sketchaccess_token
expire after 1 hour
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
client_id=...& client_secret=...& refresh_token=...& grant_type=refresh_token
Will the new token based authentication be implemented in the future release?
Just found https://github.com/yutter/ArduinoJWT, which could make it easier implement Service account support directly on the ESP.
Can you please elaborate on how to use this? I'm new to this authorization thing and its very confusing. I'm afraid that once the database secrets are fully deprecated, my software won't work anymore, so I'd like to implement token authorization as soon as possible.
Hi there, new to the rep and have been playing around with the library but also running into this authentication issue. Trying to set up a home control system that allows different people in my house to control ESP-based switches, but want to use user-based auth to limit access only to a subset of the database (e.g. those switches they're authorized to access). Seems well documented on the firebase side but this library can't handle authentication beyond the deprecated database secret. Very willing to help out with the issue but not sure where to start. :/ Cheers David
@davido1992 thanks for reaching out, I think a proper solution for this would be to either use oauth2 end user credentials or a jwt service account.
Sadly it looks like Firebase Admin custom token don't really work with the REST API.
@proppy, can you elaborate on how to use OAuth 2.0 on esp? Is it doable with a 3rd party library or something? I intend to make an authentication with esp on firebase and create an user there, the same way I'd do with an iOS app or Android app. Thanks.
Does anybody have a working example of esp8266 connected to firebase?
@proppy can you provide end user credentials example please?
@beratuslu we would need to implement some refresh logic using the oauth2 endpoint: https://developers.google.com/identity/protocols/OAuth2InstalledApp#offline
Any news about this issue ?
@proppy please can you provide example...
Hi @beratuslu,
As described in https://github.com/firebase/firebase-arduino/issues/224#issuecomment-273981906 I think we should modify https://github.com/firebase/firebase-arduino/blob/master/src/Firebase.cpp#L91 to refresh the get a new refresh token when it expires.
Something like this could work:
http_->setReuseConnection(true);
http_->begin('www.googleapis.com', '/oauth2/v4/token');
http_->sendRequest('POST', 'client_id=...&client_secret=...&refresh_token=...&grant_type=refresh_token');
And then insert the new access token in the Authorization
header or in the query string (if the former doesn't work).
@proppy Is the firebase-arduino library modified to use oauth2 instead and no secret key?
@proppy what if we generate access token from service accounts using a custom cloud function? they are free to use to certain amount. it is not ideal solution since you still need to authenticate yourself to the cloud function in some way (which could be a shared secret given as parameter), but that should be a choice of the user of this library.
@kotl I think we need something that the device can refresh.
Either by reusing the jwt Arduino integration from @gguuss Cloud IoT Core library or embededing end users credentials (refresh_token) on the device and implementing OAuth2 refresh: https://developers.google.com/identity/protocols/OAuth2InstalledApp#offline
I'd be in favor of the former as it allow to give device a dedicated identity (service account)
In order to support it in the library we would need to: -replace ?auth= with ?access_token -embed client_id, client_secret in the sketch -use a third-party tool (ex: oauth2playground) to initialily generate the access_token/refresh_token pair -embed the refresh_token in the sketch -implement the refresh logic in the library since access_token expire after 1 hour
I think the questions of creating Oauth tokens and using them should be kept separate. The suggested changes from @proppy would enable this project to use a provided token instead of a db secret.
How you get them does not matter for the implementation and can be determined at a later point.
Any news on this topic?
Any news about it? It's a core feature, with the lack of it even the simplest integration between arduino and firebase would not be possible. I'm praying for the guys who knows/can implement this feature = ]
+1 this feature is a must-have!
@proppy
I've started exploring how can we get there. Managed to get ID token and then authenticated REST request to RTDB, generated through NodeJS, but without using anything from Firebase Admin / Client SDK. This means that we just need to translate this code into Arduino C++ and use ArduinoJWT library and one https request to get idToken. This simulates generation of custom tokens on the server side and then using signInWithCustomToken on client side, but all done on the client instead. I still believe a better way would be to do this through a Cloud Function that accepts parameters like email/password for generating access token, but we can probably support both methods eventually since once you have id token, it works.
In this sample you will need to copy sample_data.js into data.js and provide appropriate fields. https://github.com/kotl/firebase-arduino/tree/AUTH/contrib/auth Run 'node auth_jwt.js > test.sh' and then 'sh test.sh' will retrieve data from RTDB.
Updated July 15: turns out, we don't need to create tokens if we decide to use only email/password auth. In a new sample I made: https://github.com/kotl/firebase-arduino/blob/AUTH/contrib/auth/auth_email.js A simple https request to identity toolkit is all you need to mint idToken.
@kotl but we still to implement refresh for the token as well?
@kotl
Hi, could you explain implementation of you method, where i should add this auth_email.js ? into the project or upload to Firebase ? Thanks in advance.
I would love for this to work - is there anything I can do to help?
Edited: After googling more about firebase and cloud function, I agreed with @kotl that using signInWithCustomToken will be the best solution, as we can get away with forgotten password or stupid password. IMHO, the authentication can be done from app/service/web, like many said, it doesn't matter once have the first token, but can be done possibly with these steps:
Does anyone know how to get this library to work with a initial token for now? Has been playing around with @proppy 's suggestion but don't seem to work.
Any news :(
No updates on this currently. You may want to take a look at Google Cloud IoT Core's Arduino client which can interface with Firebase.
In case anyone needs it This great library solved the problem by auth with email and password
In case anyone needs it This great library solved the problem by auth with email and password
I have tried, it doesn't work.
The error I get is: "Error in get, API key not valid. Please pass a valid API key."
@engrkhan
The error is the Firebase server authentication error.
You should use the Web API key that belongs to the selected project in the project settings. You can read this doc where to get the Web API key.
If you have the question, please open the issue there.
@mobizt
Thanks for the reply.
Yes, the problem is not with the library. It worked great on ESP8266 when I used the Web API key and my email credentials in the following example: https://github.com/mobizt/Firebase-ESP8266/tree/master/examples/Authentications/Email_Password
I could do both set and get operations in my Firebase RTDB.
Surprisingly when I run the same code on my ESP32, it fails quoting the reason "Permission Denied". I am trying hard but couldn't resolve it till now. I will open a new issue.
Thanks again.
@engrkhan
Please update the Firebase-ESP32 library and try again because the latest version of ESP8266 and ESP32 Firebase libraries are using the same source code.
@mobizt
Both the libraries are up-to-date.
Just confirming: Firebase Arduino Client Library for ESP8266 and ESP32, Version 2.0.10 Firebase ESP32 Client: Version 3.8.19
Still getting the error on ESP32: Set int test... FAILED REASON: Permission denied
ESP8266 is good: Set int test... PASSED PATH: /FirebaseIOT/tyW*****883/humidity TYPE: int ETag: 7ysMph9WPitGP7poMnMHMVPtUlI= VALUE: 0
@engrkhan
Are you using the same code in both library?
Please try below simple code for both ESP32 and ESP8266.
#if defined(ESP32)
#include <WiFi.h>
#include <FirebaseESP32.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
#endif
#define FIREBASE_HOST "xxxxxxxxxxxxx.firebaseio.com"
#define API_KEY "xxxxxxxxxxxxxxxxxx"
#define USER_EMAIL "xxxxxxx@gmail.com"
#define USER_PASSWORD "xxxxxxx"
#define WIFI_SSID "xxxxxxxxxx"
#define WIFI_PASSWORD "xxxxxxxxxxxx"
FirebaseAuth auth;
FirebaseConfig config;
FirebaseData fbdo;
void tokenStatusCallback(TokenInfo info);
void setup()
{
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
config.host = FIREBASE_HOST;
config.api_key = API_KEY;
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;
config.token_status_callback = tokenStatusCallback;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
}
void tokenStatusCallback(TokenInfo info)
{
if (info.status == token_status_error)
{
Serial.printf("Token error code: %d, message: %s\n", info.error.code, info.error.message.c_str());
}
if (info.status == token_status_ready)
{
if (Firebase.setString(fbdo, "/Test123", "Hello World! " ))
{
Serial.println("store data ok");
}
else
{
Serial.println("error, " + fbdo.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
}
else
{
Serial.printf("Token status code: %d\n", info.status);
}
}
void loop()
{
}
@engrkhan
In ESP32 which supports multitasking, you may need to wait for the token generation to be ready before calling the Firebase functions.
Before calling the Firebase functions, just use this to check the ready state of token.
TokenInfo info = Firebase.authTokenInfo();
if (info.status == token_status_ready)
{
//Do your Firebase calls.
}
or simpler
if (Firebase.authTokenInfo().status == token_status_ready)
{
//Do your Firebase calls.
}
@mobizt
I have tried both ways i.e., using Firebase_ESP_Client.h for both ESP8266 and ESP32, and their individual libraries as you suggested (please see the code start below). I still get the same problem: Permission denied.
/***********Original example: File -> Examples -> Firebase Arduino Client -> Authentications -> Email_Password
#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>
*/
//************* As suggested by @mobizt 24/03/2021 on github issue#224.#if defined(ESP32)
#include <WiFi.h>
#include <FirebaseESP32.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
#endif
/* 1. Define the WiFi credentials */
#define WIFI_SSID "xxxxxxxxxx"
#define WIFI_PASSWORD "xxxxxxxxxxx"
.
.
.
Ultimately I tried it using the FirebaseJson object and it worked fine on ESP32. I must give credit to the following link: https://www.electroniclinic.com/esp32-firebase-tutorial-send-sensor-data-to-google-firebase-database/
Thanks again for your time and help. I appreciate it greatly.
@engrkhan
Did you try the code I provide above comment?
Permission denied is because the id token was not ready or invalid when you call the Firebase.
@mobizt
Yes, I do check the ready state of the token before I update the RTDB. The code that you have suggested in your comment is already being part of the example that I am trying: https://github.com/mobizt/Firebase-ESP32/tree/master/examples/Authentications/Email_Password
Still getting "Permission Denied".
@engrkhan
I'll confirm the test yesterday that ESP32 and the library test is ok.
I create a fresh new Gmail account, and use it to create the new project, create new RTDB database, enable Email/Password provider, create the project user with email and password.
The RTDB security rules are set to allow read and write in the test mode.
Copy the Web API key, database host (from the RTDB console) and user Email and password to the sketch and test with ESP32 without problem.
In your case, if you sure you never missed these setup steps, please try a different ESP32 device and WiFi internet access point.
Here is the link https://youtu.be/1kqj7sWDslY for the clear solution to access the data base secretes from firebase latest version which shows up Database secrets are currently deprecated ans use a legacy Firebase token generator. Update your source code with the Firebase Admin SDK.
I hope this helps someone
Since Database secret are now being deprecated would it be possible to use new token generation. Can it be done on ESP8266 ? -> Database secrets are currently deprecated and use a legacy Firebase token generator. Update your source code with the Firebase Admin SDK.