FirebaseExtended / firebase-arduino

Arduino samples for Firebase.
Apache License 2.0
945 stars 494 forks source link

split transport from main Firebase object #70

Open proppy opened 8 years ago

proppy commented 8 years ago

In order to be portable across multiple IoT platform we should split the transport from the main Firebase* class.

The core of the library would be a set of portable class for holding the db url, the credentials and building method payload.

And then there would be transport class for each platform:

A main for the curl platform could look like this:

#include "Firebase.h"
#include "FirebaseCurlTransport.h"

int main() {
  Firebase firebase("example.firebaseio.com", "secret");
  FirebaseGet getLogs = firebase.get("/logs");

  FirebaseCurlTransport transport;
  transport.write(getLogs);
  std::string result;
  transport.read(&result);
  std::cout << result << std::endl;
}

A main for the Arduino platform could loop like this:

#include "Firebase.h"
#include "FirebaseArduinoESP8266Transport.h"

FirebaseCurlTransport transport;
Firebase firebase("example.firebaseio.com", "secret");

void setup() {
   // optional warm up connect
  transport.connect(firebase);
}

void loop() {
   transport.write(firebase.get("/logs"));
   String result;
   transport.read(&result);
}
ed7coyne commented 8 years ago

How about something like:

#include "Firebase.h"
#include "FirebaseArduinoESP8266Transport.h"

FirebaseESP8266Transport transport;
Firebase firebase("example.firebaseio.com", "secret");

void setup() {
   // optional warm up connect
  transport.connect(firebase);
}

void loop() {
  FirebaseGet get(firebase, "/logs");
  transport.execute(get);
  String result = get.raw_response();
  String timestamp = get['timestamp'];
}

This allows us to encapsulate the response parsing inside of the objects as well.

I am still a little fuzzy on how stream will work if the transport is not owned by the command object though.

proppy commented 8 years ago

I am still a little fuzzy on how stream will work if the transport is not owned by the command object though.

So what I liked about the read write interface, is that stream becomes:

transport.write(firebase.stream("/foo");
while (transport.available()) {
   String event;
   transport.read(&event);
}

And it actually close to what's happening on the wire:

ed7coyne commented 8 years ago

hmm.. just seems really low level to me. The user is then responsible for managing the state of the connection (i.e. in a stream or out of a stream). They are responsible for knowing to read all responses or they may get a surprising response later on (i.e. they send a PUT then a GET, then read expecting the response to the GET).

Also, without response parsing there doesn't seem to be much to this library. You still need to study the REST api to understand what to expect back.

I feel our goal should be to encapsulate all of the wire protocol and webby-ness (json, urls, headers, http codes) away and provide a c-style RPC interface. You provide structured data as a input and get structured data as an output.

proppy commented 8 years ago

So I still plan to parse the response, the read(String) would just return raw body and we should have read(int), and we can add json decoding too because that's transport specific (i.e: we can use ArduinoJson on arduino and another json lib for the linux transport).

I'm totally down to provide more friendly interface on top, but I just like to get this low level layer working on ESP and Linux first.

proppy commented 6 years ago

This should be fixed with #353