[SOLVED] Pushing event history to firebase via streams

Hi,
I am working to migrate my code to the V2 APIs from V1. I decided to use a Firebase hosted database and use the Streams API to make my frontend respond to smartContract events.

I got the basics link to work following your tutorials. In the previous V1, I recollect it was possible to gather the history of past events onto the database. Is it possible to do something similar with Streams?

ie. could I re-trigger past events throughout the stream to populate the firebase database collections? Alternatively, is there any script I could use to re-fill my firebase with those past-events?

As of now streams only provide real time data. However as an alternate you can use the web3 API endpoints to get the previous contract events which then can be saved to your backend database.

Are there existing scripts to do this? Essentially, I would use web3 to fetch all events logs and push them there?

You can find the SDK example snippet from this doc on how to use getcontractevents.

For testing the endpoint use this swagger URL.
https://deep-index.moralis.io/api-docs-2.1/#/Events/getContractEvents

I don’t have an example showing how to save it on db. You will mostly get the required data from the API response and save it to the firestore db.

1 Like

For those interested, the following fetch all events from a polygon contract and seems to match what Moralis is pushing up to Firebase. Now I am working on saving it on Firebase. This does feel a bit like reimplementing Moralis backend but can be useful.

var contractABI = require("<path_contract_here.json>");
contractABI = contractABI.abi;
var Web3 = require(“web3”);
var web3 = new Web3(new Web3.providers.HttpProvider(‘https://polygon-rpc.com/’));
const REACT_APP_CONTRACT_URL = ‘<contract_address_here>’
const first_block = <int_of_contract_deployment_here>

async function loadContract() {
return new web3.eth.Contract(contractABI, REACT_APP_CONTRACT_URL);
}

const AllEvents = async () => {
contract = await loadContract();
var receivedallEvents = await contract.getPastEvents(“allEvents”, {fromBlock:first_block, toBlock: “latest”})
var list_data = []
for (var event of receivedallEvents) {
var tmp_event = {};
tmp_event[“name”] = event[“event”]
tmp_event[“blockNumber”] = event[“blockNumber”]
var block_data = await web3.eth.getBlock(event[“blockNumber”])
tmp_event[“blackTimestamp”] = block_data[“timestamp”]
tmp_event[“address”] = event[“address”]
tmp_event[“blockHash”] = event[“blockHash”]
tmp_event[“transactionHash”] = event[“transactionHash”]
tmp_event[“chainId”] = 137
tmp_event[“confirmed”] = true
tmp_event[“logIndex”] = event[“logIndex”]
localReturn = event[“returnValues”]
for(var key in localReturn) {
if (isNaN(parseInt(key))) {
tmp_event[key] = localReturn[key]
}
}
list_data.push(tmp_event)
}

return list_data;
};

const result = AllEvents()
result.then((value)=>{console.log(value.length)})

1 Like

The following seems to do the trick

const admin = require(‘firebase-admin’);
const crypto = require(‘crypto’);

var contractABI = require("<path_contract_here.json>");
contractABI = contractABI.abi;
var Web3 = require(“web3”);
var web3 = new Web3(new Web3.providers.HttpProvider(‘https://polygon-rpc.com/’));
const REACT_APP_CONTRACT_URL = ‘<contract_address_here>’
const first_block = <int_of_contract_deployment_here>
const last_block = <int_of_last_block_here>
async function loadContract() {
return new web3.eth.Contract(contractABI, REACT_APP_CONTRACT_URL);
}

function generateUniqueString() {
return crypto.randomBytes(20).toString(‘hex’);
}

const AllEvents = async () => {
contract = await loadContract();
var receivedallEvents = await contract.getPastEvents(“allEvents”, {fromBlock:first_block, toBlock: last_block})
var list_data = []
for (var event of receivedallEvents) {
var tmp_event = {};
tmp_event[“name”] = event[“event”]
tmp_event[“blockNumber”] = event[“blockNumber”]
var block_data = await web3.eth.getBlock(event[“blockNumber”])
tmp_event[“blockTimestamp”] = block_data[“timestamp”]
tmp_event[“address”] = event[“address”]
tmp_event[“blockHash”] = event[“blockHash”]
tmp_event[“transactionHash”] = event[“transactionHash”]
tmp_event[“chainId”] = 137
tmp_event[“confirmed”] = true
tmp_event[“logIndex”] = event[“logIndex”]
localReturn = event[“returnValues”]
for(var key in localReturn) {
if (isNaN(parseInt(key))) {
tmp_event[key] = localReturn[key]
}
}
list_data.push(tmp_event)
}

return list_data;
};

const result = AllEvents()

// Initialize the Firebase Admin SDK with a service account key file
admin.initializeApp({
credential: admin.credential.cert("<path_firebase_cred_here.json>"),
databaseURL: ‘https://<database_name_here>.firebaseio.com’
});

const firestore = admin.firestore();

result.then((all_records) => {
// Add data to the Cloud Firestore
for(var local_event in all_records) {
var unique_id = generateUniqueString()
var docRef = firestore.collection(’/moralis/events/Demo’).doc(unique_id);
docRef.set(all_records[local_event])
}
}
)

Special thanks to ChatGPT

2 Likes

Hey @jerome,

just to confirm that you have solve your issue in this conversation thread?

Is there still any existing issue that we can help with? :grinning_face_with_smiling_eyes:

No, this works
I am now working to remove all calls to moralis query object and replace with firebase.

1 Like