Firebase/Firestore 配置文件更新不成功

Posted

技术标签:

【中文标题】Firebase/Firestore 配置文件更新不成功【英文标题】:Firebase/Firestore profile update not successful 【发布时间】:2021-11-13 04:06:32 【问题描述】:

我有一个带有 firestore 数据库的 react-native 应用程序。我想通过添加个人资料图片来更新用户个人资料。在我的控制台上,我更新成功,但用户的数据通常不会在数据库中更新。所以每当我刷新时,图片就会消失。我的代码如下:

const You = (props) => 
  const dispatch = useDispatch();
  const user = useSelector(currentUser);
  const  name, department, photoURL  = user;

  const [modalVisible, setModalVisible] = useState(false)

  const [selectedImage, setSelectedImage] = useState(null)
  
  
  let openImagePickerAsync = async () => 
    let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) 
      alert("Permission to access camera roll is required!");
      return;
    

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    
    if (pickerResult.cancelled === true) 
      return;
    

    setSelectedImage(pickerResult.uri);
  

  const uploadProfilePicture = async() => 
    if (selectedImage == null) 
      return null;
     else 
      const response = await fetch(selectedImage);
      console.log(response)
      const blob = await response.blob();
      const childPath = `profilePicture/$firebase.auth().currentUser.uid/$Math.random().toString(36)`

      const task = firebase
        .storage()
        .ref()
        .child(childPath)
        .put(blob);

      const taskProgress = (snapshot) => 
        console.log('Transferred: ', snapshot.bytesTransferred)
      
      
      const taskCompleted = () => 
        task.snapshot.ref.getDownloadURL()
          .then((snapshot) => 
            console.log('snap ',snapshot);
            console.log('Done')  
            saveProfilePicture(snapshot)
          )
      

      const taskError = (snapshot) => 
        console.log('Error: ', snapshot)
      

      task.on("state_changed", taskProgress, taskError, taskCompleted)
      
    
  

  const saveProfilePicture = (profilePictureURL) => 
    const userProfile = firebase.auth().currentUser;

    userProfile.updateProfile(
      photoURL: profilePictureURL
    ).then(() => 
      console.log("status: " + 'update success');
      dispatch(login(
        photoURL: profilePictureURL
      ))
    ).catch((error) => 
      console.log("error: ",error)
    );

  


  useEffect(() => 
    uploadProfilePicture();

  , [selectedImage])
  
 
  return (
    <SafeAreaView style=styles.container>
     
      
      <View style=justifyContent: 'center', alignItems: 'center', marginVertical: 5>
        <View style=borderColor: purple, borderRadius: 4>
                   
          <Avatar
            rounded
            size="xlarge"
            title=extractInitials(name)
            source= 
              uri: photoURL,
            
          />

          <Ionicons
            name=
              Platform.OS === 'ios'
                ? 'ios-camera'
                : 'md-camera'
            
            color=purple_70
            size=26
            style=styles.icon
            onPress=() =>
              openImagePickerAsync()
            
          />
        </View>
        <View style= justifyContent: 'center', alignItems: 'center', marginTop: 5 >
          <Text style=fontWeight: 'bold', color: darkerPurple>name</Text>
          <Text>Department: convertToUppercase(department)</Text>
        </View>
      </View>

        /* TODO: List archived issues here */
      /* <View style=marginVertical: 12>
        <Text style=styles.boldText>
          Archived Issues
        </Text>
        <View style=backgroundColor: white, paddingVertical: 8>
          <Text>List archived issues here</Text>
        </View>
      </View> */
      
      <View style=marginVertical: 12>
        <Text style=styles.boldText>
          Help
        </Text>
        <View style=backgroundColor: white, paddingVertical: 10>
          /* showBox && <View style=styles.box></View> */
          <View style=styles.helpItem>
            <MaterialCommunityIcons
              name="card-account-phone"
              size=18
              color=purple_80
              style=paddingRight: 12
            />
            <Pressable onPress=() => navigation.navigate("Contact Us")>
              <Text>Contact us</Text>
            </Pressable>
          </View>
          <View style=styles.helpItem>
            <MaterialCommunityIcons
              name="comment-question"
              size=18
              color=purple_80
              style=paddingRight: 12
            />
            <Pressable onPress=() => navigation.navigate("Faq")>
              <Text>Faq</Text>
            </Pressable>
          </View>
          <View style=styles.helpItem>
            <MaterialCommunityIcons
              name="file-document-outline"
              size=18
              color=purple_80
              style=paddingRight: 12
            />
            <Pressable onPress=() => navigation.navigate("Terms and Conditions")>
              <Text>Terms &#38; conditions</Text>
            </Pressable>
          </View>
        </View>
      </View>
      
      <View style=styles.signOut>
        <MaterialCommunityIcons
          name="logout"
          size=18
          color=red
          style=paddingRight: 12
        />
        <Text 
          style=[styles.boldText, color: red] 
          onPress=onSignOut 
        >
          Sign Out
        </Text>
      </View>
      
      <View style=styles.signOut>
        <MaterialCommunityIcons
          name="delete"
          size=18
          color=red
          style=paddingRight: 12
        />
        <Text 
          style=[styles.boldText, color: red] 
        >
          Delete account
        </Text>
      </View>
    
    </SafeAreaView>
  );

我的 redux 更新了,但 firestore 数据没有。请问,我哪里错了?

【问题讨论】:

你能解释一下什么是行不通的吗?你说“firestore”数据不会改变。您没有在问题中使用任何与 Firestore 相关的代码。 saveProfilePicture 函数用于更新 Firestore, 该代码直接更新auth 个人资料图片,不会更改firestore 中的任何内容。如果您愿意在女巫上分享保存数据的路径,我可以为您提供将其在 Firestore 中更改为的代码。 我保存数据的路径在 uploadProfilePicture 函数中可以看到,我有这样的东西: const blob = await response.blob(); const childPath = profilePicture/$firebase.auth().currentUser.uid/$Math.random().toString(36) 这是 Firebase 存储中的路径。您真的想在 Firestore 数据库中拥有相同的数据库吗?通常我们在那里使用users路径作为用户数据,并将用户ID作为ID。 【参考方案1】:

代码中存在一些错误和一些误解。首先是代码。

你这样调用你的函数

uploadProfilePicture();

但您希望这里有profilePictureURL

const saveProfilePicture = (profilePictureURL) => 

另外,您只更新auth 个人资料图片,数据库中没有任何内容。

这是一个应该可以正常工作并符合您期望的示例:

const saveProfilePicture = (profilePictureURL) => 
  const userProfile = firebase.auth().currentUser;
  var db = firebase.firestore();

  //Here we save the picture to the user auth
  userProfile
    .updateProfile(
      photoURL: profilePictureURL,
    )
    .then(() => 
      console.log("status: " + "update success");
      // Here we save to the firestore database
      db.collection("users") // Change this path to something else if you want
        .doc(firebase.auth().currentUser.uid)
        .set(
          
            photoURL: profilePictureURL,
          ,
           merge: true 
        )
        .then(() => 
          dispatch(
            login(
              photoURL: profilePictureURL,
            )
          );
        );
    )
    .catch((error) => 
      console.log("error: ", error);
    );
;

useEffect(() => 
  // You forgot to add selctedImage here
  uploadProfilePicture(selectedImage);
, [selectedImage]);

您可以根据需要更改数据库中的路径,但请确保您的数据库规则允许您在其中保存一些内容。

【讨论】:

【参考方案2】:

查看我对 saveProfilePicture 函数所做的更改。感谢大家的贡献。

const saveProfilePicture = (profilePictureURL) => 
    const userProfile = firebase.auth().currentUser;

    return firebase.firestore()
      .collection("users")
      .doc(firebase.auth().currentUser.uid)
      .update(
        photoURL: profilePictureURL
      )
      .then(() => 
        console.log("Update success");
      )
      .catch((error) => console.error("Error: ", error));

  

【讨论】:

以上是关于Firebase/Firestore 配置文件更新不成功的主要内容,如果未能解决你的问题,请参考以下文章

Firestore 配置 - Firebase

如何更新单个 Firebase Firestore 文档

Firebase:Firestore 未在 Cloud Function 的计划函数中更新数据

Firebase Firestore 不更新电子邮件验证状态

删除 SwiftUI 后 Firebase Firestore 不更新 UI

Android Firebase FireStore实时更新分页