Git Product home page Git Product logo

firebase-arduino's Introduction

FirebaseArduino

Build Status Join the chat at https://gitter.im/googlesamples/firebase-arduino Documentation Status

This repo contains a collection of samples and an Arduino library that show how to call the Firebase API from the ESP8266 Arduino core.

Status

Status: Frozen

This repository is no longer under active development. No new features will be added and issues are not actively triaged. Pull Requests which fix bugs are welcome and will be reviewed on a best-effort basis.

If you maintain a fork of this repository that you believe is healthier than the official version, we may consider recommending your fork. Please open a Pull Request if you believe that is the case.

Samples

  • FirebaseDemo - shows the FirebaseArduino API methods.
  • FirebaseRoom - shows how to push sensor data and trigger actuator from Firebase.
  • FirebaseStream - shows the FirebaseArduino streaming API.
  • FirebaseNeoPixel - shows how to control an array of LEDs from a Firebase web app.

Documentation

Dependencies

  • FirebaseArduino now depends on ArduinoJson library instead of containing it's own version of it. Please either use Library Manager or download specific version of the library from github. We recommend that ArduinoJson is at least version 5.13.1

  • ESP8266 Core SDK. We recommend using officially tagged releases and it should be at least 2.4.1

Disclaimer

This is not an official Google product.

firebase-arduino's People

Contributors

alexkorovyansky avatar aliafshar avatar avolkovi avatar ed7coyne avatar gguuss avatar gitter-badger avatar ikshitiz avatar kevinwlee avatar kotl avatar kptdobe avatar proppy avatar raemondbw avatar salqadri avatar samtstern avatar tricksumo avatar vothanhkiet avatar yehiyam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

firebase-arduino's Issues

Getting started friction log

Here's my stream of consciousness as I got started. Feel free to break it up into other issues, close because I'm a n00b, whatever :)

Hardware

I wasn't sure which device should get male headers or female
I looked at pictures on adafruit's site and both versions exist
I reasoned that I want to be able to read the oled display, so i put female headers on the esp8266 board
Consider adding a picture of the assembled hardware

Push sample

Started at 2:15 pm

Started from here - https://github.com/googlesamples/firebase-arduino
Didn't have ESP8266 set up, so went here - https://github.com/esp8266/Arduino#using-git-version-
Followed instructions
Opened push sample
Removed auth() call and pointed it to mimming.firebaseio-demo.com. I'll use a demo firebase and unauthenticated pushes
Tried to compile push sample, saw error

In file included from FirebasePush_ESP8266.ino:20:0:
/arduino-sketchbook/libraries/firebase-arduino/Firebase.h:24:25: fatal error: ESP8266WiFi.h: No such file or directory
 #include <ESP8266WiFi.h>
                         ^
compilation terminated.
Error compiling.

I suspect my ESP8266 installation is bunk
Find reveals that the library is in the sketchbook/hardware/esp8266com/…

$ find ./ | grep ESP8266WiFi.h
.//esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h

Maybe it's because my Arduino SDK is out of date. It's 1.6.4. Time to update to 1.6.7
Time to try to build again
Not sure which board I have or stuff so I guessed (it'd help if you gave advice hewre)

Looks like it worked
Now… I have no idea what that sample is supposed to do.
It'd help if the readme described what it should do or had a picture or something
It's not doing anything
Oh it looks like wifi config is not set
It'd help if the readme gave step by step about everything that i need to change (so far firebase name, auth token, and wifi info)
Set SSID to MyOpenWifiNetwork
Not working yet - wifi connect
Nothing in Firebase
Oh the code writes to serial. I'll look there next
I see that it's not connecting
(IT'd help if we had sample output on the docs)
Looks like it's having trouble connecting to GoogleGuest :(
Went to Google for help on wifi.connect - https://www.arduino.cc/en/Reference/WiFiConfig
Looks like I was running the function wrong. I thought it was taking "parameter name", "value" turns out it was "SSID", "Password" :
Building again

3:00pm (45 min in)
It connects now! Yay! But new problem

connecting........
connected: 192.168.146.4
Firebase request failed
POST /logs.json: connection refused
0�~?�4�!�{�OAa�connecting......
connected: 192.168.146.4
Firebase request failed
POST /logs.json: connection refused
0�~?�4�!�{�OAa�connecting....
connected: 192.168.146.4
Firebase request failed
POST /logs.json: connection refused

Maybe it does not work on demo firebases?
I created a new firebase : espbutton.firebaseio.com
I gave auth() my secret
Building again
Yay it's writing!

connecting......
connected: 192.168.123.45
{"name":"-K9-A4Ib_T54zVlGU9F2"}
{"-K9-A-Iy_WNj4Uu0mLen":1453849314558,"-K9-A4Ib_T54zVlGU9F2":1453849335015}

Confirmed on firebase dashboard

Bitcoin sample

Now that the push sample works, want the stream!
Opened up the other sample, the stream one.
Attempted to compile

FirebaseStream_ESP8266/FirebaseStream_ESP8266.ino:22:30: fatal error: Adafruit_SSD1306.h: No such file or directory
 #include <Adafruit_SSD1306.h>
                              ^
compilation terminated.
exit status 1
Error compiling.

:(
Went to library manager, and installed it
It'd be cool to call out that dependency on the readme?
Yay it compiles!
But I'm getting gibberish on the serial :( And the OLED isn't pretty :(
It prints a gibberish every 500ms, so I think it's trying to say connect
I added Serial.print("hello"); before the display inits. It looks like starting up the display is what distorts the serial
Moved the display init to bottom of setup
Still goes gibberish once the oled's begin is called
Commenting out all of the display code. I want to verify the firebase part works (just display data on serial)
Flashing again
I can see data on serial! Yay

data: {"path":"/_updated","data":"Tue Jan 26 2016 23:24:16 GMT+0000 (UTC)"}
event: 1
data: {"path":"/last","data":"389.82"}
event: 1
data: {"path":"/bid","data":"389.76"}
event: 1
data: {"path":"/ask","data":"389.96"}

Now to figure out what's up with the OLED
Taking a step back to verify the oled display works. I'll go through - https://learn.adafruit.com/digital-display-badge
Saw in this code that OLED_RESET should probalby be 3 (since it's same PCB)
https://learn.adafruit.com/digital-display-badge/code
Chagned OLED_RESET from 10 to 3
Flashed
Yay it's fixed

Now I want to get it to work with some LEDs, maybe APA102s? It worked really easy until I burned up my level shifter :D

split transport from main Firebase object

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:

  • FirebaseArduinoESP8266
  • FirebaseCurl
  • FirebasePhoton
  • FirebaseArduinoSerialAT

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);
}

Refactor Firebase class, improve api, change style

I think we should refactor the Firebase class, while it is young and small seems the best time to do it.

I am personally against to the current paradigm of "do an action" then "explicitly check for error()". While this is exposed in professional apis (win32 comes to mind) it is usually not well regarded as those interfaces age. It is error prone as it is very easy to not explicitly check for the error than use the result as if it succeeded. It also has thread safety implications.

I propose that instead we return a FirebaseResult class that contains the status code and an optional result body and exposes helpers like is_error().

I also think we should take this time to standardize style guidelines for this class. Personally I propose using the Google C Style guide (https://google.github.io/styleguide/cppguide.html) as much as they apply to wirinig in its c-likeness. I think there is value in uniformity of the code as it develops, I am open to other styles as well but I think we should try to standardize on one if we can.

I will put together a pull request reflecting this change if no one has any objections.

add README for examples

From #49

We have a proper README.md for each samples and the main librarie with:

  • Hardware assembly instructions w/ Pictures
  • Libraries dependencies with version #54
  • Step by step modification instructions
  • Sample output w/ Pictures

We should also replicate some of the content or link to it in the header comment on the samples, since the Arduino IDE won't show the README when opening examples.

2 api surfaces proposal

I find that the current API (esp, thanks to @ed7coyne refactoring & testability) strike a good compromise between user facing usability and modularity for downstream like the modem.

We chose this compromise because ongoing tension between using modern C++ idiom to make it friendly to build downstream program (like the modem) or following https://www.arduino.cc/en/Reference/APIStyleGuide and make it friendly to the lambda Arduino user, the discussion on #93 is a good illustration of this.

I'd like us to iterate on the current design to create 2 API surfaces:

  1. an Arduino-friendly 'layer' with the following properties:
    • only 1 top level type, exposed as a global Firebase object.
    • only basic type (int, float, String, bool) as arguments and return values, no stl type or pointers
    • stateful (only one operation at a time)
    • optional error handling (exposed thru boolean method: connected(), success(), failed() on the main object).
    • compose well with existing Arduino abstraction: Client
    • exposed as one dependency.
  2. a C++ friendly 'layer' with the following properties:
    • follow modern C++ best practice
    • strict and verbose error handling
    • leverage heavily memory management of the STL and built in containers
    • mockable and testable
    • decouple transport types from the firebase protocol implementation and its payloads.

I think that with #90 we're very close to 2. but I'd like to work on building 1. on top of it: as part of #80 #81 #82.

Let's discuss it :)

add pairing mode

with a hardware switch that put the esp8266 in AP mode, and give a way to send command over http or a serial repl over telnet.

remove child method

Now that FirebaseRef are gone, having a mutable child() method feels weird. Instead each API call should take an explicit path and overload for each base type:

firebase.push("sensor1/value", 42.0);
firebase.push("thing/state", "opened");

calling set() while streaming crashes

Summary

If you call stream() and then attempt to call set() from from another client, the device panics :(

Steps

Run this code

#include <Firebase.h>


Firebase fbase = Firebase("espbutton.firebaseio.com").auth("REDACTED");
Firebase fbaseStream = Firebase("espbutton.firebaseio.com").auth("SAME_VALUE_ALSO_REDACTED");


void setup() {

  Serial.begin(9600);

  Serial.println("Hello world!");  

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

  fbaseStream.stream("/hello");
}

void loop() {
  fbase.set("/", "{\"hello\": \"world\"}");
}

Result

Hello world!
connecting..
connected: 192.168.123.45

Panic /arduino-sketchbook/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp:495 ax_port_malloc

ctx: cont 
sp: 3fff10a0 end: 3fff1520 offset: 01b0

>>>stack>>>
3fff1250:  3fff28f0 00004000 3fff80b5 40203b80  
3fff1260:  36363636 3fff2f58 3fff2f64 40203b0d  
3fff1270:  3fff80b5 00000000 3fff28f0 402294fc  
3fff1280:  3fff80b5 00000000 3fff28f0 4022a8fe  
3fff1290:  00000001 00000001 3fff80a8 40228a9a  
3fff12a0:  e8dc11b0 a2dee883 b0599e2f 000000b9  
3fff12b0:  00000010 3fff80b5 3fff299c 3fff12f0  
3fff12c0:  3fff80b5 3fff28c0 000000e2 00000010  
3fff12d0:  3fff28f0 3fff80b5 00000010 00000010  
3fff12e0:  3fff80b5 00000000 3fff28f0 4022a31e  
3fff12f0:  8ef9144a 72ca9803 93bab03d 66081d08  
3fff1300:  d258f652 00000000 00000034 40229a40  
3fff1310:  00020016 00000014 00000010 00000010  
3fff1320:  0000002f 00000016 3ffe9388 00000004  
3fff1330:  0000002f 3fff28f0 3fff28f0 4022a456  
3fff1340:  0000002f 3fff80a5 3fff28f0 4022a645  
3fff1350:  3fff283c 4021cafa 3fff27c0 00000000  
3fff1360:  00000000 3fff2158 3fff28f0 4022a6d0  
3fff1370:  3fff1d28 3fff1d28 00000001 3fff0394  
3fff1380:  3fff0398 3fff1d28 3fff1c20 40203906  
3fff1390:  b86ac568 3fff1c88 40205524 3fff1c88  
3fff13a0:  00000001 000001bb 3fff1d28 40203bd2  
3fff13b0:  3ffe9190 b86ac568 3fff01f8 402066b0  
3fff13c0:  3fff2430 000001bb 3fff1d28 40202dc5  
3fff13d0:  3ffe9190 b86ac568 3ffe9190 b86ac568  
3fff13e0:  3fff2288 00000000 3ffe8fe2 40205328  
3fff13f0:  3fff0294 00000000 3fff0294 40203be8  
3fff1400:  00000034 00000001 3fff0294 40204398  
3fff1410:  3ffe8ce3 00000012 3fff0294 40204918  
3fff1420:  3ffe8fe2 4010743f 3fff1450 3fff04f4  
3fff1430:  3fff14e8 3fff0294 3fff0294 40203f94  
3fff1440:  3ffe8ce3 00000000 3fff1494 40202660  
3fff1450:  00000000 00000000 00000000 0000008c  
3fff1460:  3ffe8ce3 3fff14dc 3fff0294 40202843  
3fff1470:  00000133 3ffe8ccb 3fff01f8 4020670a  
3fff1480:  3ffe8c89 00000012 3fff14dc 40206762  
3fff1490:  00000000 3fff22c0 0000003f 00000034  
3fff14a0:  3fffdad0 00000000 3fff14dc 3fff04f4  
3fff14b0:  3fffdad0 3fff0294 3fff14d0 40202903  
3fff14c0:  3fff1600 00000000 3fff04ed 4020250d  
3fff14d0:  3ffe8c82 00f0ffff fe9fa8c0 3fff1c88  
3fff14e0:  0000001f 00000012 3fff1608 0000000f  
3fff14f0:  00000001 00000000 00000000 feefeffe  
3fff1500:  feefeffe 00000000 3fff04ed 40205570  
3fff1510:  feefeffe feefeffe 3fff0500 40100114  
<<<stack<<<
��!����!��

URL parser could be more flexible

Passing a trailing slash and/or including a leading protocol causes a failure on write. A helpful warning about malformed URL or a 404 would be nice, but it would be better to be to include a smarter parser.

enforce the connection boilerplate on every sample

We should unify wifi/firebase connection boilerplate in setup() and add travis check for this.

It could look like this.

#define FIREBASE_HOST "example.firebaseio.com"
#define FIREBASE_AUTH "token_or_secret"
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"

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

  // connect to wifi.
  WiFi.begin(WIFI_SSID, WIFI_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);
}

add two step initialization

In order to follow pattern from other Arduino library and play nicely with setup() and loop() lifecycle, we should support two step initialization.

Firebase fbase;

void setup() {
   fbase.begin("url", "auth");
}

FirebaseStream and FirebasePush did not work together

Hi,
I tried to run firebase stream example (FirebaseStream_ESP8266) on device and it worked as I expected.
After that, I tried to add a new feature in which the device push feedback message to firebase cloud after getting data from stream. I used FirebasePush to implement this. (I also tried FirebasePush separately and it worked fine.)
Unfortunately, it ended up with an exception.

Exception (28):
epc1=0x40206efe epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

and FirebasePush error message look like this one.

POST /feedbacks.json: -3

Did I make something incorrectly ?
Any help will be appreciated.

My modified code is as follow.

//
// 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.
//

// FirebaseStream_ESP8266 is a sample that stream bitcoin price from a
// public Firebase and optionally display them on a OLED i2c screen.

#include <Firebase.h>
#include <ESP8266WiFi.h>
//#include <Adafruit_GFX.h>
//#include <Adafruit_SSD1306.h>
#include <ArduinoJson.h>

//#define OLED_RESET 3
//Adafruit_SSD1306 display(OLED_RESET);

Firebase fbase("<my firebase cloud>");
FirebaseStream stream;

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

  //display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  //display.display();

  // 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());
  stream = fbase.stream("/bitcoin/last");  
}


void loop() {
  if (stream.error()) {
    Serial.println("streaming error");
    Serial.println(stream.error().message());
  }

  if (stream.available()) {
     String event;
     auto type = stream.read(event);
     Serial.print("event: ");
     Serial.println(type);
     if (type == FirebaseStream::Event::PUT) {
       StaticJsonBuffer<200> buf;
       Serial.print("data: ");
       Serial.println(event);
       JsonObject& json = buf.parseObject((char*)event.c_str());
       String path = json["path"];
       float data = json["data"];       

       // TODO(proppy): parse JSON object.
       //display.clearDisplay();
       //display.setTextSize(2);
       //display.setTextColor(WHITE);
       //display.setCursor(0,0);
       //display.println(path.c_str()+1);
       //display.println(data);
       //display.display();

      //Added code: Send feedback to firebase cloud.
      FirebasePush fbPush = fbase.push("/feedbacks", "{\"received\":\"true\"}");
      if (fbPush.error()) {
            Serial.println("Firebase set failed");
            Serial.println(fbPush.error().message());  
            delay(100);
            return;
          }
          Serial.println(fbPush.name());
     }
  }   
}

explicit begin/end for managing connection

currently the first push/val will take a longer time because of the first connection.

it would be better to warm up the connection on begin() instead and tear everything down with end().

As pointed by @yhua537 in #375 that would allow sketches to trade additional latency for more memory available.

Auth error -- Any documentation to help debug?

Is there any a good place to start searching for documentation that might help me resolve the error below?

connecting......
connected: 192.168.11.136
Firebase push failed
POST /logs.json?auth=############: -1 (Replaced secret with ## for post)

wrap WifiSecureClient by default

Using Arduino Client interface like it was originally before d72b3ff.

This could make the API a lot easier Serial.print(Firebase.push(...)), but we still need a way to perform operation in a non blocking way while leaving tight control on the arduino main loop, ex:

FirebaseReq req = Firebase.child("logs").push("{\".sv\": \"timestamp\"}");
while (!req.done()) {
   req.transfer();
   // blink some led while transferring
   digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
Serial.print(req.response());

We also need a way to dump the intermediate request headers for debugging and offer a way to stream the request body.

laziness

The library should give a way to construct Firebase call independently from executing them.

That could enable:

  • keeping static const version of repeated request.
  • fine grained control over HttpClient instance used to execute request.
  • overload for testing, portability and debugging

That could be done by adding FirebaseCall::execute(HttpClient&) and having the default constructor call it directly to preserve the easy Firebase.push/get/* flow, while still allowing user to call it manually when constructing FirebasPush/FirebaseGet/* object manually with two step initialization (see #58)

Firebase with Arduino IDE makes function definitions in .ino order dependant

This issue was hidden away in a larger project but I've managed to simplify it down to a very basic definition of a function in the .ino.
This is happening in the Ardunino IDE, but works fine with Visual Micro.

//#include <Firebase.h>

void setup() {

  test();
}

void loop() {
}

void test(){
  Serial.println("woo");
}

This complies, but if you uncomment the #include, and it says test() hasn't been declared

C:\Users\Daniel\AppData\Local\Temp\arduino_0c4b0ad3e77c4cee76cbe62faa3f08cf\FirebasePush_ESP8266.ino: In function 'void setup()':

FirebasePush_ESP8266:5: error: 'test' was not declared in this scope

   test();

        ^

exit status 1
'test' was not declared in this scope

But moving test() definition to the top of the file it works again.

#include <Firebase.h>

void test(){
  Serial.println("woo");
}


void setup() {

  test();
}

void loop() {
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.