首页 > 解决方案 > how can i remove data from firebase by React native?

问题描述

I'm making SNS app with React Native & Firebase.

Finally, I can create a Post Title & Post Description and show it as a Flatlist.

But I don't know how to remove each post.

i already made TouchableOpacity for removing data inside Flatlist. but i don't know how i make it as a remove button.............

Please let me know where to check the document or link.

Or give me a hint. (In fact, it's been stuck here for almost two weeks.)

-----action/post

export const updateTitle = (text) => {
  return { type: "UPDATE_TITLE", payload: text };
};
export const updateDescription = (text) => {
  return { type: "UPDATE_DESCRIPTION", payload: text };
};

export const uploadPost = () => {
  return async (dispatch, getState) => {
    try {
      const { post, user } = getState();
      const upload = {
        postTitle: post.title || " ",
        postDescription: post.description || " ",
        uid: user.uid,
        photo: user.photo || " ",
        username: user.username,
        likes: [],
        comments: [],
        date: new Date().getTime(),
      };
      const ref = await db.collection("posts").doc();
      upload.id = ref.id;
      ref.set(upload);
    } catch (e) {
      alert(e);
    }
  };
};

export const getPosts = () => {
  return async (dispatch, getState) => {
    try {
      const posts = await db.collection("posts").onSnapshot(function (posts) {
        let array = [];
        posts.forEach((post) => {
          array.push(post.data());
        });
        dispatch({
          type: "GET_POSTS",
          payload: orderBy(array, "date", "desc"),
        });
      });
    } catch (e) {
      alert(e);
    }
  };
};

----reducers/index

const post = (state = null, action) => {
  switch (action.type) {
    case "UPDATE_TITLE":
      return { ...state, title: action.payload };
    case "UPDATE_DESCRIPTION":
      return { ...state, description: action.payload };
    case "GET_POSTS":
      return { ...state, feed: action.payload };
    case "GET_COMMENTS":
      return { ...state, comments: action.payload };
    default:
      return state;
  }
};

----screen/home

import React from "react";
import { Ionicons, SimpleLineIcons } from "@expo/vector-icons";
import {
  Text,
  View,
  TouchableOpacity,
  FlatList,
  StatusBar,
} from "react-native";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { getPosts, likePost, unlikePost } from "../actions/post";
import styles from "../styles";
import moment from "moment";
import "moment/locale/ko";
moment.locale("ko");

class Home extends React.Component {
  componentDidMount() {
    this.props.getPosts();
  }

  likePost = (post) => {
    const { uid } = this.props.user;
    if (post.likes.includes(uid)) {
      this.props.unlikePost(post);
    } else {
      this.props.likePost(post);
    }
  };

  render() {
    if (this.props.post === null) return null;
    return (
      <View style={styles.container}>
        <StatusBar barStyle="dark-content" />
        <View style={styles.topTitle}>
          <Text style={styles.topTitleText}>We are Vendor</Text>
        </View>
        <FlatList
          onRefresh={() => this.props.getPosts()}
          refreshing={false}
          data={this.props.post.feed}
          keyExtractor={(item) => item.id}
          renderItem={({ item }) => {
            const liked = item.likes.includes(this.props.user.uid);
            return (
              <View>
                <View style={styles.height}>
                  <View
                    style={[
                      styles.row,
                      styles.space,
                      styles.marginTop,
                      styles.marginHorizontal,
                    ]}
                  >
                    <Text style={[styles.bold, styles.size23, styles.grayDark]}>
                      {item.postTitle}
                    </Text>
                  </View>
                  <View
                    style={[styles.row, styles.space, styles.marginHorizontal]}
                  >
                    <Text
                      style={[
                        styles.bold,
                        styles.grayDark,
                        styles.marginTop7,
                        styles.size15,
                      ]}
                    >
                      {"  "}
                      {item.username}
                    </Text>
                    <Text style={[styles.gray, styles.small]}>
                      {moment(item.date).format("ll")}{" "}
                      {moment(item.date).fromNow()}
                    </Text>
                  </View>
                  <View
                    style={[
                      styles.marginTop,
                      styles.marginHorizontal,
                      styles.container,
                    ]}
                  >
                    <Text
                      style={styles.grayDark}
                      ellipsizeMode={"middle"}
                      numberOfLines={11}
                    >
                      {item.postDescription}
                    </Text>
                  </View>
                </View>
                <View
                  style={[styles.row, styles.marginHorizontal, styles.space]}
                >
                  <View style={[styles.row]}>
                    <TouchableOpacity
                      onPress={() => this.likePost(item)}
                      style={[styles.marginRight]}
                    >
                      <Ionicons
                        style={{ margin: 5 }}
                        color="#db565b"
                        name={liked ? "ios-heart" : "ios-heart-empty"}
                        size={25}
                      />
                    </TouchableOpacity>
                    <TouchableOpacity
                      onPress={() =>
                        this.props.navigation.navigate("Comment", item)
                      }
                    >
                      <SimpleLineIcons
                        style={{ margin: 5 }}
                        color={"#3478f6"}
                        name="bubble"
                        size={22}
                      />
                    </TouchableOpacity>
                  </View>
                  {this.props.user.uid == item.uid && (
                    <TouchableOpacity>
                      <Text>THIS IS REMOVE BUTTON</Text>
                    </TouchableOpacity>
                  )}
                </View>
                <View style={[styles.center, styles.border90]} />
              </View>
            );
          }}
        />
      </View>
    );
  }
}

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({ getPosts, likePost, unlikePost }, dispatch);
};

const mapStateToProps = (state) => {
  return {
    post: state.post,
    user: state.user,
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);

I would like get advise about removing comments

----action/post

export const getComments = (post) => {
  return (dispatch) => {
    dispatch({
      type: "GET_COMMENTS",
      payload: orderBy(post.comments, "date", "desc"),
    });
  };
};

export const addComment = (text, post) => {
  return (dispatch, getState) => {
    const { uid, photo, username } = getState().user;
    let comments = cloneDeep(getState().post.comments.reverse());
    try {
      const comment = {
        comment: text,
        commenterId: uid,
        commenterPhoto: photo || "",
        commenterName: username,
        date: new Date().getTime(),
        postTitle: post.postTitle,
        postDescription: post.postDescription,
        postUser: post.username,
      };
      console.log(comment);
      db.collection("posts")
        .doc(post.id)
        .update({
          comments: firebase.firestore.FieldValue.arrayUnion(comment),
        });
      comment.postId = post.id;
      comment.postTitle = post.postTitle;
      comment.postDescription = post.postDescription;
      comment.postUser = post.username;
      comment.uid = post.uid;
      comment.type = "COMMENT";
      comments.push(comment);
      dispatch({ type: "GET_COMMENTS", payload: comments.reverse() });

      db.collection("activity").doc().set(comment);
    } catch (e) {
      console.error(e);
    }
  };
};

----comment screen

import React from "react";
import styles from "../styles";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import {
  Text,
  View,
  TextInput,
  FlatList,
  KeyboardAvoidingView,
  TouchableOpacity,
  StatusBar,
  Animated,
  Dimensions,
} from "react-native";
import { addComment, getComments } from "../actions/post";
import moment from "moment";
import "moment/locale/ko";
moment.locale("ko");
import { Swipeable } from "react-native-gesture-handler";

class Comment extends React.Component {
  state = {
    comment: "",
  };

  componentDidMount = () => {
    const { params } = this.props.route;
    this.props.getComments(params);
  };

  postComment = () => {
    const { params } = this.props.route;
    this.props.addComment(this.state.comment, params);
    this.setState({ comment: "" });
  };

  rightActions = (dragX) => {
    const scale = dragX.interpolate({
      inputRange: [-100, 0],
      outputRange: [1, 0.9],
      extrapolate: "clamp",
    });
    const opacity = dragX.interpolate({
      inputRange: [-100, -20, 0],
      outputRange: [1, 0.9, 0],
      extrapolate: "clamp",
    });
    const deleteItem = async (id) => {
      await db.collection("posts").doc(id).delete();
      console.log("Deleted ", id);
    };

    return (
      <TouchableOpacity>
        <Animated.View style={[styles.deleteButton, { opacity: opacity }]}>
          <Animated.Text
            style={{
              color: "white",
              fontWeight: "800",
              transform: [{ scale }],
            }}
            onPress={() => deleteItem(item.id)}
          >
            DELETE COMMENT
          </Animated.Text>
        </Animated.View>
      </TouchableOpacity>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <StatusBar barStyle="dark-content" />
        <KeyboardAvoidingView
          enabled
          behavior="padding"
          style={[styles.container, styles.marginTop]}
        >
          <FlatList
            keyExtractor={(item) => JSON.stringify(item.date)}
            data={this.props.post.comments}
             renderItem={({ item }) => (
              <View>
                <Swipeable
                  renderRightActions={(_, dragX) => this.rightActions(dragX)}
                >
                  <View style={[styles.row, styles.space]}>
                    <View style={{ margin: 10 }}></View>
                    <View style={[styles.container, styles.left]}>
                      <Text style={styles.marginTop}>
                        <Text style={[styles.bold, styles.grayDark]}>
                          {item.commenterName}
                        </Text>

                        <Text style={styles.gray}>님이 댓글을 달았습니다.</Text>
                      </Text>
                      <Text style={[styles.gray, styles.marginTop5]}>
                        {item.comment}
                      </Text>
                      <Text
                        style={[styles.gray, styles.small, styles.marginTop]}
                      >
                        {moment(item.date).format("ll")}{" "}
                        {moment(item.date).fromNow()}
                      </Text>
                    </View>
                  </View>
                </Swipeable>
              </View>
            )}
          />
          <TextInput
            style={styles.input}
            onChangeText={(comment) => this.setState({ comment })}
            value={this.state.comment}
            returnKeyType="send"
            placeholder="댓글을 남겨주세요."
            onSubmitEditing={this.postComment}
          />
        </KeyboardAvoidingView>
      </View>
    );
  }
}

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({ addComment, getComments }, dispatch);
};

const mapStateToProps = (state) => {
  return {
    user: state.user,
    post: state.post,
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Comment);

`

标签: reactjsfirebasereact-nativereduxgoogle-cloud-firestore

解决方案


创建一个删除带有 id 的文档的函数

const deleteItem = async (id) => {
    await db.collection('names').doc(id).delete();
    console.log('Deleted ', id)
}

...
{this.props.user.uid == item.uid && (
   <TouchableOpacity onPress={() => deleteItem(item.uid)}>
     <Text>THIS IS REMOVE BUTTON</Text>
  </TouchableOpacity>
)}

推荐阅读