Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

switch to ESP8266HTTPClient #22

Merged
merged 1 commit into from
Dec 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 24 additions & 34 deletions Firebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//
#include "Firebase.h"

const char* firebaseFingerprint = "C1 56 CD D8 49 A3 7D D2 1D 49 60 7E 0D 59 A7 7C C1 0E 58 D2";
const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;

FirebaseRoot Firebase;
Expand All @@ -27,60 +27,50 @@ FirebaseRef& FirebaseRef::root() {
return _root;
}

String FirebaseRef::set(const String& value) {
return _root.buildRequest("PUT", _path, value);
String FirebaseRef::val() {
return _root.sendRequest("GET", _path);
}

String FirebaseRef::push(const String& value) {
return _root.buildRequest("POST", _path, value);
return _root.sendRequest("POST", _path, (uint8_t*)value.c_str(), value.length());
}

FirebaseRef FirebaseRef::child(const String& key) {
return FirebaseRef(_root, _path + "/" + key);
}

FirebaseRoot::FirebaseRoot() : FirebaseRef(*this, "") {
_http.setReuse(true);
}

void FirebaseRoot::begin(const String& host) {
FirebaseRoot& FirebaseRoot::begin(const String& host) {
_host = host;
return *this;
}

void FirebaseRoot::auth(const String& token) {
_token = token;
FirebaseRoot& FirebaseRoot::auth(const String& auth) {
_auth = auth;
return *this;
}

FirebaseRef FirebaseRoot::child(const String& key) {
return FirebaseRef(*this, key);
}

String FirebaseRoot::buildRequest(const String& method, const String& path, const String& data) {
String req;
req += method + " /" + path + ".json";
if (_token.length() > 0) {
req += "?auth=" + _token;
String FirebaseRoot::sendRequest(const char* method, const String& path, uint8_t* value, size_t size) {
_error.reset();
String url = "/" + path + ".json";
if (_auth.length() > 0) {
url += "?auth=" + _auth;
}
req += " HTTP/1.1\r\n";
req += "Host: " + _host + "\r\n";
req += "User-Agent: Arduino\r\n";
req += "Connection: close\r\n";
if (data.length()) {
req += "Content-Length: ";
req += data.length();
req += "\r\n\r\n";
req += data;
_http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
int statusCode = _http.sendRequest(method, value, size);
if (statusCode < 0) {
_error.set(statusCode,
String(method) + " " + url + ": "
+ HTTPClient::errorToString(statusCode));
return "";
}
return req;
}

const char* FirebaseRoot::host() const {
return _host.c_str();
}

uint16_t FirebaseRoot::port() const {
return firebasePort;
}

const char* FirebaseRoot::fingerprint() const {
return firebaseFingerprint;
return _http.getString();
// NOTE: no end() because reuse.
}
60 changes: 41 additions & 19 deletions Firebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,54 +14,76 @@
// limitations under the License.
//

// Firebase is an helper library for building Firebase request.
// TODO(proppy): add value() method for GET.
// firebase-arduino is an Arduino client for Firebase.
// It is currently limited to the ESP8266 board family.

// TODO(proppy): add set() method for PUT.
// TODO(proppy): add update() method for PATCH.
// TODO(proppy): add remove() method for DELETE.
// TODO(proppy): add helper for decoding response.
// TODO(proppy): add connect() + non blocking
#ifndef firebase_h
#define firebase_h

#include "Arduino.h"
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>

class Client;
class FirebaseRoot;

// FirebaseRef is a reference in the firebase hierarchy.
// FirebaseRef is a node in the firebase hierarchy.
//
// Methods `set()` and `push()` returns the HTTP request as a raw
// `String`, the requests then need be sent using an Arduino Wifi,
// Ethernet or GSM `Client`.
// Methods val() and push() performs respectivly HTTP GET and POST
// requests on the corresponding child reference and return the
// response body.
class FirebaseRef {
public:
FirebaseRef(FirebaseRoot& root, const String& path);
FirebaseRef& root();
String set(const String& value);
String val();
String push(const String& value);
FirebaseRef child(const String& key);
private:
FirebaseRoot& _root;
String _path;
};

// FirebaseRoot is a root of firebase hierarchy.

// FirebaseError is a string representation of a firebase HTTP error.
class FirebaseError {
public:
operator bool() const { return _code < 0; }
int code() const { return _code; }
const String& message() const { return _message; }
void reset() { set(0, ""); }
void set(int code, const String& message) {
_code = code;
_message = message;
}
private:
int _code = 0;
String _message = "";
};


// FirebaseRoot is the root node of firebase hierarchy.
//
// A global `Firebase` instance is available for convenience, and need
// to be initialized with the `begin()` and `auth()` methods.
class FirebaseRoot : public FirebaseRef {
friend FirebaseRef;
public:
FirebaseRoot();
void begin(const String& host);
void auth(const String& token);
const char* host() const;
uint16_t port() const;
const char* fingerprint() const;
FirebaseRef child(const String& key);
FirebaseRoot& begin(const String& host);
FirebaseRoot& auth(const String& auth);
FirebaseRef child(const String& key);
const FirebaseError& error() { return _error; }
private:
String buildRequest(const String& method, const String& path, const String& data);
String sendRequest(const char* method, const String& path, uint8_t* value = NULL, size_t size = 0);
HTTPClient _http;
String _host;
String _token;
String _auth;
FirebaseError _error;
};

extern FirebaseRoot Firebase;
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
# firebase-arduino

This sample show how to call firebase from an arduino sketch.

*This is not an official Google product*.
This sample shows how to call [Firebase](https://www.firebase.com/) from the [ESP8266 Arduino core](https://github.com/esp8266/Arduino).

## Requirements

- 1 Arduino compatible esp8266 board.
- Arduino 1.6.x
- 1 [ESP8266 Arduino board](https://www.adafruit.com/products/2821).
- [Arduino 1.6.x](https://www.arduino.cc/en/Main/Software)
- ESP8266 Arduino board definition [(master branch)](https://github.com/esp8266/Arduino#using-git-version-)

## Setup

- Clone the repo in your Arduino libraries directory.
- open the `FirebasePush_ESP8266` example.
- Update `WIFI_SSID` `WIFI_PASSWORD` `FIREBASE_HOST` `FIREBASE_TOKEN` constant.
- Replace `SSID` `PASSWORD` `example.firebaseio.com` `secret_or_token` `node` placeholders.

## Run
- Open firebase dashboard on `/logs.json`.

- Open firebase dashboard.
- Power up the arduino board.
- Notice the new entry.

*This is not an official Google product*.
75 changes: 41 additions & 34 deletions examples/FirebasePush_ESP8266/FirebasePush_ESP8266.ino
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
// FirebasePush_ESP8266 is a sample that write a timestamp to a firebase
// everytime it is powered on.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
//
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// FirebasePush_ESP8266 is a sample that push a new timestamp to firebase
// on each reset.

#include <Firebase.h>

#define WIFI_SSID "..."
#define WIFI_PASSWORD "..."
#define FIREBASE_HOST "..."
#define FIREBASE_TOKEN "..."

void setup() {
Serial.begin(9600);

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

// connect to wifi.
WiFi.begin("SSID", "PASSWORD");
Serial.print("connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("connected: ");
Serial.println(WiFi.localIP());

Firebase.begin(FIREBASE_HOST);
Firebase.auth(FIREBASE_TOKEN);

WiFiClientSecure wifiClient;
if (!wifiClient.connect(Firebase.host(), Firebase.port())) {
Serial.print("connected failed");
// get firebase child reference.
FirebaseRef logsRef = Firebase.begin("example.firebaseio.com")
.auth("secret_or_token")
.child("node");

// add a new entry.
String logEntry = logsRef.push("{\".sv\": \"timestamp\"}");
// handle error.
if (Firebase.error()) {
Serial.println("Firebase request failed");
Serial.println(Firebase.error().message());
return;
}
if (!wifiClient.verify(Firebase.fingerprint(), Firebase.host())) {
Serial.println("certificate verification failed");
return;
}

String req = Firebase.child("logs").push("{\".sv\": \"timestamp\"}");
Serial.println("request:");
Serial.println(req);
wifiClient.print(req);

Serial.println("response:");
while(wifiClient.connected() || wifiClient.available() > 0) {
String data = wifiClient.readStringUntil('\n');
Serial.println(data);
}
Serial.println(logEntry);
// print all entries.
Serial.println(logsRef.val());
}

void loop() {
}
}