1

I am using react-redux-firebase. This is how my firebase data looks like once user submit the form: enter image description here

It pushes information to "contacts" and images to "uploadedFiles"(also used for file Storage path). I really want to have it as one item. Something like:

contacts = {
 kydfsdcfasdfsadf :{
   email: "user@gmail.com",
   firstName: Tom,
   lastName : "Smith",
   uploasedFiles:{
     downloadURL:"dsfsdfsdsdvsdfgdsfgds",
     fullPath:"dfsdfsdf",
     mame:"q34deser4wefwsdf"
   }
 }
}

I feel like I should use Populate, but I can not find how to populate one item with another. Will really appreciate any suggestion and useful links.

Here is the code: AddContactForm.js

import { Field, reduxForm } from 'redux-form';
import { browserHistory } from 'react-router';
import Uploader from '../components/Uploader';

const capitalize = value => value.charAt(0).toUpperCase() + value.substring(1);
const lower = value => value && value.toLowerCase();


const AddContactForm = props => {
    const { handleSubmit } = props;
    return (
      <div>
          <h1> Add New Contact</h1>
          <hr />
            <form onSubmit={handleSubmit}>
              <div>
                <label htmlFor="firstName">First Name</label>
                <Field name="firstName" component="input" type="text" normalize={capitalize} />
              </div>
              <div>
                <label htmlFor="lastName">Last Name</label>
                <Field name="lastName" component="input" type="text" normalize={capitalize} />
              </div>
              <div>
                <label htmlFor="email">Email</label>
                <Field name="email" component="input" type="email" normalize={lower} />
              </div>
              <Uploader />
              <button type="submit">Submit</button>
              <button onClick={() => { browserHistory.push('/'); }} >Cancel</button>
            </form>
        </div>
    );
};

AddContactForm = reduxForm({
  // a unique name for the form
  form: 'contact'
})(AddContactForm)

export default AddContactForm;

Uploader.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose, bindActionCreators } from 'redux';
import { firebaseConnect, dataToJS, getFirebase } from 'react-redux-firebase';
import { map } from 'lodash';
import Dropzone from 'react-dropzone';


// Path within Database for metadata (also used for file Storage path)
const filesPath = 'uploadedFiles';

class Uploader extends Component {

  onFilesDrop(files) {
      const firebase = getFirebase();
    // Uploads files and push's objects containing metadata to database at dbPath
    // uploadFiles(storagePath, files, dbPath)
    firebase.uploadFiles(filesPath, files, filesPath);
}

  onFileDelete(file, key) {
      const firebase = getFirebase();
    // Deletes file and removes metadata from database
    // deleteFile(storagePath, dbPath)
    firebase.deleteFile(file.fullPath, `${filesPath}/${key}`);
  }

  render() {
    const { uploadedFiles } = this.props
    return (
      <div>
        <Dropzone onDrop={this.onFilesDrop}>
          <div>
            Drag and drop files here
            or click to select
          </div>
        </Dropzone>
        {
          uploadedFiles &&
            <div>
              <h3>
                Uploaded file(s):
              </h3>
              {
                map(uploadedFiles, (file, key) => (
                  <div key={file.name + key}>
                    <span>{file.name}</span>
                    <button onClick={() => this.onFileDelete(file, key)}>
                      Delete File
                    </button>
                  </div>
                ))
              }
            </div>
          }
      </div>
    );
  }
}

Uploader.propTypes = {
    firebase: PropTypes.object.isRequired,
    uploadedFiles: PropTypes.object
};

export default compose(
  firebaseConnect([
    filesPath
  ]),
  connect(
    ({ firebase }) => ({
      uploadedFiles: dataToJS(firebase, filesPath)
    })
  )
)(Uploader);

AddContact.js

import React from 'react';
import { getFirebase, firebaseConnect, dataToJS } from 'react-redux-firebase';
import { browserHistory } from 'react-router';
import { connect } from 'react-redux';
import { compose } from 'redux';
import AddContactForm from './AddContactForm';

class AddContact extends React.Component {
    submit(values) {
      const firebase = getFirebase();
      firebase
      .push('contacts', values)

    //   .push('contacts', Object.assign({}, values, { img: 'here I need to pass uploadedFiles' }))

      .then(() => {
        browserHistory.push('/');
    });
}
    render() {
            const { uploadedFiles } = this.props;
            const uploadArr = uploadedFiles&&Object.values(uploadedFiles);
            const fileToAdd = uploadedFiles&&uploadArr[uploadArr.length-1].downloadURL

            console.log('uploadedFiles!', uploadedFiles&&fileToAdd);
      return (
            <div className="container">
                <AddContactForm onSubmit={this.submit} />
            </div>
      );
    }
}

export default compose(
  firebaseConnect([
    { path: 'contacts', queryParams: ['orderByValue'] },
    { path: 'uploadedFiles', queryParams: ['orderByValue'] }
  ]),
  connect(
    (state) => ({
      uploadedFiles: dataToJS(state.firebase, 'uploadedFiles')
    }),
  )
)(AddContact)
Etoya
  • 239
  • 1
  • 7
  • 16
  • could you post your code so that it's easy for us to guide you – grgmo Nov 09 '17 at 22:17
  • @grgmo thank you for reply! I posted it – Etoya Nov 11 '17 at 14:20
  • do you have access to both information about contact and uploadedFiles when you want to save it? or do you save contact while you wait for files to upload, and save images path later once it finishes – grgmo Nov 11 '17 at 17:58
  • @grgmo so once user click Uploader "Drag and drop files here or click to select" and choose the picture, it will save selected image to Firebase's uploadedFiles. As for information about contact, it will only be submitted to firebase once user click "Submit". – Etoya Nov 12 '17 at 12:23

1 Answers1

1

I would suggest to follow the React Redux "Way" of dealing with Firebase and that to create an Action that deals with Firebase which i am not sure if i am missing it in your code or not. However, when you upload the files in storage you need to set the URI into your Firebase database reference. you should get a URI as a result when you upload a file into the Firebase Storage.

export function createAccount(data, picture) {
  const { fname, lname, email, password, image } = data;

      storage.child(`/${picture.name}/${new Date().getTime()}`).put(image[0]).then((snapshot) => {
        database.ref('contacts').child(youruserID).set({
         email: "user@gmail.com",
   firstName: Tom,
   lastName : "Smith",
          uploadedfile: snapshot.metadata.downloadURLs[0]
        });
      });

}
Chosen
  • 847
  • 2
  • 9
  • 21