chin14
chin14

Reputation: 214

Material UI Avatar Image Upload

I managed it to make an Avatar chooser, but I don't know how to save the picture in Firebase or how to even save it as a Profile picture.

This is how it looks like:

enter image description here

This comes out if I click on the button:

enter image description here

I can choose a pic, but it just not saving it anywhere and also not displaying the picture in the avatar. My code:

function Profile(props, navigation) {
  const classes = useStyles();
  const user = useUser(props.route.params.uid);
  const [time, setTime] = useState("7:30");
  const [timing, setTiming] = useState([]);
  const [timeAfternoon, setTimeAfternoon] = useState("7:30");
  const [timingAfternoon, setTimingAfternoon] = useState([]);
  const [sickDaysStart, setSickDaysStart] = useState(Date.now());
  const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
  const [sickDaysConfirm, setSickDaysConfirm] = useState([]);
  const [donwloadURL, setDownloadURL] = useState([]);

  const onLogout = () => {
    firebase.auth().signOut();
  };

  function handelSickDaysStart(e) {
    setSickDaysStart(e.target.value);
  }
  function handelSickDaysEnd(e) {
    setSickDaysEnd(e.target.value);
  }
  function handleTime(e) {
    setTime(e.target.value);
  }
  function handleTimeAfternoon(e) {
    setTimeAfternoon(e.target.value);
  }
  function delayMorning() {
    db.collection("delayInTheMorning")
      .doc()
      .set({
        time,
        user,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setTiming([...timing, { time }]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }
  function delayAfternoon() {
    db.collection("delayInTheAfternoon")
      .doc()
      .set({
        timeAfternoon,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }

  function sickDaysStartEnd() {
    db.collection("DaysofSickness")
      .doc()
      .set({
        sickDaysStart,
        sickDaysEnd,
        user,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setSickDaysConfirm([
          ...sickDaysConfirm,
          { sickDaysStart, sickDaysEnd },
        ]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }

  function isCurrentUserProfile() {
    if (props.route.params.uid === firebase.auth().currentUser.uid) {
      return true;
    } else {
      return false;
    }
  }
  async function handleFileInputChange(e) {
    const files = e.target.files;
    const file = files[0];

    const storage = firebase.storage();
    const usersImageRef = storage
      .ref()
      .child(`users/${user.uid}/profilepicture.jpg`);

    const snap = await usersImageRef.put(file);

    const donwloadURL = await snap.ref.getDownloadURL();
    setDownloadURL(donwloadURL);

    await firebase.auth().currentUser.updateProfile({ photoURL: donwloadURL });
  }

  if (user === null) {
    return <div className={classes.root} />;
  }
  return (
    <ScrollView style={styles.root}>
      <Container className={classes.div}>
        <input
          accept="image/*"
          className={classes.input}
          id="contained-button-file"
          multiple
          type="file"
          onChange={handleFileInputChange}
        />
        <label>
          <IconButton>
            <Avatar
              src="../assets/ana.png"
              style={{
                margin: "10px",
                width: "60px",
                height: "60px",
              }}
            />
          </IconButton>
        </label>
        <Typography className={classes.text}> {user.name} </Typography>
        <Typography className={classes.text}> {user.email} </Typography>

        {isCurrentUserProfile() ? (
          <Button
            className={classes.btn}
            size="large"
            variant="outlined"
            onClick={() => onLogout()}
          >
            Logout
          </Button>
        ) : null}
      </Container>
      <Card className={classes.div}>
        {/* //Verspätung */}
        <CardContent className={classes.cardBackGround}>
          <Typography variant="h5" className={classes.cardTyp}>
            {" "}
            Verspätung{" "}
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="time"
              label="Zeit"
              type="time"
              defaultValue="07:30"
              InputLabelProps={{
                shrink: true,
              }}
              inputProps={{
                step: 300, // 5 min
              }}
              onChange={(value) => {
                handleTime(value);
              }}
            />
            <Button className={classes.cardBtn} onClick={() => delayMorning()}>
              Absenden
            </Button>
          </Container>
        </CardContent>

        {/* //Krankenmledungen */}
        <CardContent className={classes.cardBackGround}>
          <Typography variant="h5" className={classes.cardTyp}>
            Krankenmledungen
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="date"
              label="Von"
              type="date"
              defaultValue="2021-09-14"
              className={classes.textField}
              InputLabelProps={{
                shrink: true,
              }}
              onChange={(value) => {
                handelSickDaysStart(value);
              }}
            />

            <TextField
              id="date"
              label="bis"
              type="date"
              defaultValue="2021-09-20"
              className={classes.textField}
              InputLabelProps={{
                shrink: true,
              }}
              onChange={(value) => {
                handelSickDaysEnd(value);
              }}
            />
          </Container>
          <Button
            className={classes.cardBtnKM}
            onClick={() => sickDaysStartEnd()}
          >
            Absenden
          </Button>
        </CardContent>

        {/* //Verspätung Abolung*/}
        <CardContent className={classes.cardBackGround}>
          <Typography variant="h5" className={classes.cardTyp}>
            {" "}
            Verspätung Abholung
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="time"
              label="Zeit"
              type="time"
              defaultValue="07:30"
              InputLabelProps={{
                shrink: true,
              }}
              inputProps={{
                step: 300, // 5 min
              }}
              onChange={(value) => {
                handleTimeAfternoon(value);
              }}
            />
            <Button
              className={classes.cardBtn}
              onClick={() => delayAfternoon()}
            >
              Absenden
            </Button>
          </Container>
        </CardContent>
      </Card>

      {/* <List> */}
      {/* Verspätungs Liste */}
      {timing.map((item) => {
        return (
          <List className={classes.lists}>
            <ListItem className={classes.list1}>
              <ListItemAvatar>
                <Avatar></Avatar>
              </ListItemAvatar>
              <ListItemText
                primary={user.name}
                secondary={`Verspätung in der Früh ${item.time}`}
              />
            </ListItem>
          </List>
        );
      })}
      {/* Krankmeldung */}
      {timingAfternoon.map((item) => {
        return (
          <List className={classes.lists}>
            <ListItem className={classes.list}>
              <ListItemAvatar>
                <Avatar></Avatar>
              </ListItemAvatar>
              <ListItemText
                primary={user.name}
                secondary={`Verspätung bei der Abholung ${item.timeAfternoon}`}
              />
            </ListItem>
          </List>
        );
      })}
      {/* Verspätungs Nachmittag */}
      {sickDaysConfirm.map((item) => {
        return (
          <List className={classes.lists}>
            <ListItem className={classes.list}>
              <ListItemAvatar>
                <Avatar></Avatar>
              </ListItemAvatar>
              <ListItemText
                primary={user.name}
                secondary={`Krankmeldung von ${item.sickDaysStart} bis ${item.sickDaysEnd}`}
              />
            </ListItem>
          </List>
        );
      })}
    </ScrollView>
  );
}

There is also a imagePicker from Expo, I was thinking of trying that but I'm just not sure.

Upvotes: 2

Views: 4061

Answers (1)

Tarik Huber
Tarik Huber

Reputation: 7408

If you want to change the profile picture of a user you can use this code:

import { getAuth, updateProfile } from "firebase/auth";
const auth = getAuth();
updateProfile(auth.currentUser, {
  displayName: "User Name", photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(() => {
  // Profile updated!
  // ...
}).catch((error) => {
  // An error occurred
  // ...
});

You can find more info about it here.

To get the picture URL you would need to upload it to Firebase Storage and get the downloadURL:

import { getStorage, ref, uploadBytes, getDownloadURL  } from "firebase/storage";

const storage = getStorage();
const storageRef = ref(storage, 'some-child');

// 'file' comes from the Blob or File API
uploadBytes(storageRef, file).then((snapshot) => {
  console.log('Uploaded a blob or file!');
      getDownloadURL(snapshot.ref).then((downloadURL) => {
      console.log('File available at', downloadURL);
    });
});

I would also change the input to not have multiple files to select. If you would share more of your code I can integrate those code snippets in your code in case you have problems with it.

UPDATE:

Here is the whole example. I see you use the old SDK so the example is with it:

function Profile(props, navigation) {
  const classes = useStyles();
  const user = useUser(props.route.params.uid);
  const delay = DayandTime();
  const [time, setTime] = useState("7:30");
  const [timing, setTiming] = useState([]);
  const [downloadurl, setDU] = useState("/images/example.jpg");
  const [timeAfternoon, setTimeAfternoon] = useState("7:30");
  const [timingAfternoon, setTimingAfternoon] = useState([]);
  const [sickDaysStart, setSickDaysStart] = useState(Date.now());
  const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
  const [sickDaysConfirm, setSickDaysConfirm] = useState([]);

  const onLogout = () => {
    firebase.auth().signOut();
  };

  function handelSickDaysStart(e) {
    setSickDaysStart(e.target.value);
  }
  function handelSickDaysEnd(e) {
    setSickDaysEnd(e.target.value);
  }
  function handleTime(e) {
    setTime(e.target.value);
  }
  function handleTimeAfternoon(e) {
    setTimeAfternoon(e.target.value);
  }
  function delayMorning() {
    db.collection("delayInTheMorning")
      .doc()
      .set({
        time,
        user,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setTiming([...timing, { time }]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }
  function delayAfternoon() {
    db.collection("delayInTheAfternoon")
      .doc()
      .set({
        timeAfternoon,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }

  function sickDaysStartEnd() {
    db.collection("DaysofSickness")
      .doc()
      .set({
        sickDaysStart,
        sickDaysEnd,
        user,
      })
      .then(() => {
        //If you wish to push the written data to your local state, you can do it here
        setSickDaysConfirm([
          ...sickDaysConfirm,
          { sickDaysStart, sickDaysEnd },
        ]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }

  function isCurrentUserProfile() {
    if (props.route.params.uid === firebase.auth().currentUser.uid) {
      return true;
    } else {
      return false;
    }
  }

  if (user === null) {
    return <div className={classes.root} />;
  }

  async function handleFileInputChange(e) {
    const files = e.target.files;
    const file = files[0];

    const storage = firebase.storage();
    const usersImageRef = storage
      .ref()
      .child(`users/${user.uid}/profilepicture.jpg`);

    const snap = await usersImageRef.put(file);

    const downloadURL = await snap.ref.getDownloadURL();
    setDU(downloadURL);

    await firebase.auth().updateProfile({ photoURL: downloadURL });
  }

  return (
    <ScrollView style={styles.root}>
      <Container className={classes.div}>
        <input
          accept="image/*"
          className={classes.input}
          id="contained-button-file"
          multiple
          type="file"
          onChange={handleFileInputChange}
        />
        <label htmlFor="contained-button-file">
          <IconButton>
            <Avatar
              src="/images/example.jpg"
              style={{
                margin: "10px",
                width: "60px",
                height: "60px",
              }}
            />
          </IconButton>
        </label>
        <Typography className={classes.text}> {user.name} </Typography>
        <Typography className={classes.text}> {user.email} </Typography>

        {isCurrentUserProfile() ? (
          <Button
            className={classes.btn}
            size="large"
            variant="outlined"
            onClick={() => onLogout()}
          >
            Logout
          </Button>
        ) : null}
      </Container>
      <Card className={classes.div}>
        {/* //Verspätung */}
        <CardContent>
          <Typography variant="h5" className={classes.cardTyp}>
            {" "}
            Verspätung{" "}
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="time"
              label="Zeit"
              type="time"
              defaultValue="07:30"
              InputLabelProps={{
                shrink: true,
              }}
              inputProps={{
                step: 300, // 5 min
              }}
              onChange={(value) => {
                handleTime(value);
              }}
            />
            <Button className={classes.cardBtn} onClick={() => delayMorning()}>
              Absenden
            </Button>
          </Container>
        </CardContent>

        {/* //Krankenmledungen */}
        <CardContent className={classes.cardKrankmeldung}>
          <Typography variant="h5" className={classes.cardTyp}>
            {" "}
            Krankenmledungen{" "}
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="date"
              label="Von"
              type="date"
              defaultValue="2021-09-14"
              className={classes.textField}
              InputLabelProps={{
                shrink: true,
              }}
              onChange={(value) => {
                handelSickDaysStart(value);
              }}
            />

            <TextField
              id="date"
              label="bis"
              type="date"
              defaultValue="2021-09-20"
              className={classes.textField}
              InputLabelProps={{
                shrink: true,
              }}
              onChange={(value) => {
                handelSickDaysEnd(value);
              }}
            />
          </Container>
          <Button
            className={classes.cardBtnKM}
            onClick={() => sickDaysStartEnd()}
          >
            Absenden
          </Button>
        </CardContent>

        {/* //Verspätung Abolung*/}
        <CardContent>
          <Typography variant="h5" className={classes.cardTyp}>
            {" "}
            Verspätung Abholung
          </Typography>
          <Container className={classes.cardContainer}>
            <TextField
              id="time"
              label="Zeit"
              type="time"
              defaultValue="07:30"
              InputLabelProps={{
                shrink: true,
              }}
              inputProps={{
                step: 300, // 5 min
              }}
              onChange={(value) => {
                handleTimeAfternoon(value);
              }}
            />
            <Button
              className={classes.cardBtn}
              onClick={() => delayAfternoon()}
            >
              Absenden
            </Button>
          </Container>
        </CardContent>
      </Card>

      <List>
        {/* Verspätungs Liste */}
        <ListItem>
          <ListItemAvatar>
            <Avatar></Avatar>
          </ListItemAvatar>
          <ListItemText
            primary={user.name}
            secondary={`Verspätung in der Früh ${delay}`}
          />
        </ListItem>
        {/* Verspätungs Krankmeldung */}
        <ListItem>
          <ListItemAvatar>
            <Avatar></Avatar>
          </ListItemAvatar>
          <ListItemText
            primary={user.name}
            secondary={`Krankmeldung  ${delay}`}
          />
        </ListItem>
        {/* Verspätungs Nachmittag */}
        <ListItem>
          <ListItemAvatar>
            <Avatar></Avatar>
          </ListItemAvatar>
          <ListItemText
            primary={user.name}
            secondary={`Verspätung Nachmittag  ${delay}`}
          />
        </ListItem>
      </List>
    </ScrollView>
  );
}

const mapStateToProps = (store) => ({
  currentUser: store.userState.currentUser,
  posts: store.userState.posts,
  following: store.userState.following,
});

export default connect(mapStateToProps, null)(Profile);

const useStyles = makeStyles({
  root: {
    backgroundColor: "white",
  },
  div: {
    marginTop: 20,
    marginLeft: 15,
    marginRight: 15,
    backgroundColor: "white",
  },
  avatar: {
    marginBottom: 10,
  },
  btn: {
    marginTop: 10,
    width: 250,
    marginBottom: 30,
  },
  text: {
    fontSize: 25,
    marginTop: 10,
  },
  cardTyp: {
    textAlign: "left",
    paddingLeft: 13,
  },
  cardBtn: {
    marginTop: 20,
    marginLeft: 30,
  },
  cardBtnKM: {
    marginTop: 20,
    marginLeft: 10,
  },
  cardContainer: {
    display: "flex",
  },
});

const styles = StyleSheet.create({
  root: {
    backgroundColor: "white",
  },
});

Upvotes: 2

Related Questions