在Dart Flutter中将文档添加到Firestore后,如何直接获取文档ID

时间:2020-03-26 08:40:12

标签: flutter dart google-cloud-firestore

我有此代码:

RaisedButton(
    child: Text('Add'),
    onPressed: () async {
        if (_formKey.currentState.validate()) {
            DocumentReference docRef =
                await DatabaseServices().addUserProperty(
                    user.userUid,
                    _currentPropertyName,
                    _currentPropertyNotes,
                    _currentPropertyZone,
                    _currentPropertyAddress `enter code here`,
                    _currentPropertyLandArea,
                    _currentPropertyDatePurchased,
                    _currentPropertyRatesBillingCode,
                    _currentPropertyInsurancePolicy,
                    _currentPropertyInsuranceSource,
                    _currentPropertyInsuranceExpiryDate `enter code here`,
                    _currentPropertyLegalDescription,
                    _currentPropertyValuation,
                    _currentPropertyValuationSource,
                    false,
                    Timestamp.now(),
                    Timestamp.now(),
                );
            await DatabaseServices().addPropertyUnit(
                user.userUid,
                docRef.documentID,
                'Single unit',
                '',
                '',
                0,
                false,
                false,
                Timestamp.now(),
                Timestamp.now(),
            );
            Navigator.pop(context);
        }
    })

我试图将刚生成的documentId中的'docRef.documentID'用于addUserProperty。我想将此保存为addPropertyUnit中的一个字段。我在docRef.documentID行上收到错误消息“ getter'documentID'被调用为null”。我该怎么办?

感谢建议。我确实在.then()内放置了第二个等待。我现在有了这段代码:

RaisedButton(
                child: Text('Add'),
                onPressed: () async {
                  if (_formKey.currentState.validate()) {
                    DocumentReference docRef = await DatabaseServices()
                        .addUserProperty(
                      user.userUid,
                      _currentPropertyName,
                      _currentPropertyNotes,
                      _currentPropertyZone,
                      _currentPropertyAddress,
                      _currentPropertyLandArea,
                      _currentPropertyDatePurchased,
                      _currentPropertyRatesBillingCode,
                      _currentPropertyInsurancePolicy,
                      _currentPropertyInsuranceSource,
                      _currentPropertyInsuranceExpiryDate,
                      _currentPropertyLegalDescription,
                      _currentPropertyValuation,
                      _currentPropertyValuationSource,
                      false,
                      Timestamp.now(),
                      Timestamp.now(),
                    )
                        .then((docRef) async {
                      await DatabaseServices().addPropertyUnit(
                        user.userUid,
                        'nnnnnnnnnn',
//                        docRef.documentID,
                        'Single unit',
                        '',
                        '',
                        0,
                        false,
                        false,
                        Timestamp.now(),
                        Timestamp.now(),
                      );
                      return null;
                    });
//                    print('docRef: ${docRef.documentID}');

                    Navigator.pop(context);
                  }
                })  

它的工作方式是保存一个新的PropertyUnit,但是如何将docRef.documentID从.addUserProperty传递给.addPropertyUnit()?目前,它只是保存“ nnnnnnnnnnn”。如果我定义“ DocumentReference docRef;”在“ Widget build(BuildContext context){”正下方,docRef.documentID在.addPropertyUnit中可用,但仍会收到运行时错误“ getter'documentID'被调用为null”。

addPropertyUnit的代码为:

// add a unit to a property
  Future addPropertyUnit(
    String userUid,
    String unitPropertyUid,
    String unitName,
    String unitNotes,
    String unitLeaseDescription,
    num unitArea,
    bool unitResidential,
    bool unitArchived,
    Timestamp unitRecordCreatedDateTime,
    Timestamp unitRecordLastEdited,
  ) async {
    return await userUnitCollection.document().setData(
      {
        'userUid': userUid,
        'propertyUid': unitPropertyUid,
        'unitName': unitName,
        'unitNotes': unitNotes,
        'unitLeaseDescription': unitLeaseDescription,
        'unitArea': unitArea,
        'unitResidential': unitResidential,
        'unitArchived': unitArchived,
        'unitRecordCreatedDateTime': unitRecordCreatedDateTime,
        'unitRecordLastEdited': unitRecordLastEdited,
      },
    );
  }

和addUserProperty:

 // add a property
  Future addUserProperty(
    String userUid,
    String propertyName,
    String propertyNotes,
    String propertyZone,
    String propertyAddress,
    double propertyLandArea,
    DateTime propertyDatePurchased,
    String propertyRatesBillingCode,
    String propertyInsurancePolicy,
    String propertyInsuranceSource,
    DateTime propertyInsuranceExpiryDate,
    String propertyLegalDescription,
    double propertyValuation,
    String propertyValuationSource,
    bool propertyArchived,
    Timestamp propertyRecordCreatedDateTime,
    Timestamp propertyRecordLastEdited,
  ) async {
    return await userPropertyCollection.document().setData(
      {
        'userUid': userUid,
        'propertyName': propertyName,
        'propertyNotes': propertyNotes,
        'propertyZone': propertyZone,
        'propertyAddress': propertyAddress,
        'propertyLandArea': propertyLandArea,
        'propertyDatePurchased': propertyDatePurchased,
        'propertyRatesBillingCode': propertyRatesBillingCode,
        'propertyInsurancePolicy': propertyInsurancePolicy,
        'propertyInsuranceSource': propertyInsuranceSource,
        'propertyInsuranceDate': propertyInsuranceExpiryDate,
        'propertyLegalDescription': propertyLegalDescription,
        'propertyMarketValuation': propertyValuation,
        'propertyMarketValuationSource': propertyValuationSource,
        'propertyArchived': propertyArchived,
        'propertyRecordCreatedDateTime': propertyRecordCreatedDateTime,
        'propertyRecordLastEdited': propertyRecordLastEdited,
      },
    );
  }

3 个答案:

答案 0 :(得分:1)

使用下面的代码。我相信它可以工作。

df1=tx_user[["Recency","Frequency","Revenue"]]
#standardize
names = df1.columns
# Create the Scaler object
scaler = preprocessing.StandardScaler()
# Fit your data on the scaler object
scaled_df1 = scaler.fit_transform(df1)
df1 = pd.DataFrame(scaled_df1, columns=names)
df1.head()
del scaled_df1

sklearn_pca = PCA(n_components = 2)
X1 = sklearn_pca.fit_transform(df1)
X1 = X1[:, ::-1] # flip axes for better plotting
kmeans = KMeans(3, random_state=0)
labels = kmeans.fit(X1).predict(X1)
plt.scatter(X1[:, 0], X1[:, 1], c=labels, s=40, cmap='viridis');

from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist

def plot_kmeans(kmeans, X, n_clusters=4, rseed=0, ax=None):
    labels = kmeans.fit_predict(X)

    # plot the input data
    ax = ax or plt.gca()
    ax.axis('equal')
    #ax.set_ylim(-5000,7000)
    ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2)

    # plot the representation of the KMeans model
    centers = kmeans.cluster_centers_
    radii = [cdist(X[labels == i], [center]).max()
             for i, center in enumerate(centers)]
    for c, r in zip(centers, radii):
        ax.add_patch(plt.Circle(c, r, fc='#CCCCCC', lw=3, alpha=0.5, zorder=1))

kmeans = KMeans(n_clusters=4, random_state=0)
plot_kmeans(kmeans, X1)

我们的代码之间的区别在于,此代码正在等待addUserProperty()首先完成以获取docRef对象,然后在docRef不再为null时,它将运行addPropertyUnit()函数,因此,docRef将不会空。

更新后的答案:

为您的addUserProperty使用以下代码:

RaisedButton(
            child: Text('Add'),
            onPressed: () async {
              if (_formKey.currentState.validate()) {
                DocumentReference docRef = await DatabaseServices()
                    .addUserProperty(
                  user.userUid,
                  _currentPropertyName,
                  _currentPropertyNotes,
                  _currentPropertyZone,
                  _currentPropertyAddress,
                  _currentPropertyLandArea,
                  _currentPropertyDatePurchased,
                  _currentPropertyRatesBillingCode,
                  _currentPropertyInsurancePolicy,
                  _currentPropertyInsuranceSource,
                  _currentPropertyInsuranceExpiryDate,
                  _currentPropertyLegalDescription,
                  _currentPropertyValuation,
                  _currentPropertyValuationSource,
                  false,
                  Timestamp.now(),
                  Timestamp.now(),
                );
                  await DatabaseServices().addPropertyUnit(
                    user.userUid,
                    docRef.documentID,
                    'Single unit',
                    '',
                    '',
                    0,
                    false,
                    false,
                    Timestamp.now(),
                    Timestamp.now());
               print('docRef: ${docRef.documentID}');

                Navigator.pop(context);
              }
            })  

答案 1 :(得分:0)

试试看!肯定会为您完成工作。

RaisedButton(
   child: Text('Add'),
   onPressed: () async {
     if (_formKey.currentState.validate()) {
         DocumentReference docRef = await DatabaseServices().addUserProperty(
            user.userUid,
            _currentPropertyName,
            _currentPropertyNotes,
            _currentPropertyZone,
            _currentPropertyAddress,
            _currentPropertyLandArea,
            _currentPropertyDatePurchased,
            _currentPropertyRatesBillingCode,
            _currentPropertyInsurancePolicy,
            _currentPropertyInsuranceSource,
            _currentPropertyInsuranceExpiryDate,
            _currentPropertyLegalDescription,
            _currentPropertyValuation,
            _currentPropertyValuationSource,
            false,
            Timestamp.now(),
            Timestamp.now(),
         ).then((docRef) async {

           print('addUserProperty Done');
           // docRef.documentID available here
           print('docRef: ${docRef.documentID}'); 

           await DatabaseServices().addPropertyUnit(
              user.userUid,
              docRef.documentID,
              'Single unit',
              '',
              '',
              0,
              false,
              false,
              Timestamp.now(),
              Timestamp.now(),
           ).then(() async {
             print('addPropertyUnit Done'); 
           });
         });

       Navigator.pop(context);
     }
})  

答案 2 :(得分:0)

也许考虑获取唯一的文档ID,Firestore将在发布数据之前使用该ID来发布数据。然后,您将拥有一个可同时用于addUserProperty和addPropertyUnit的ID。

生成此唯一ID的示例代码为:

DocumentReference ref = db.collection("my_collection").doc();
String myId = ref.id;

我在Firebase RTDB中使用了此技术,并且效果很好,但是我对Firestore并不熟悉,因此无法发布更新的代码。

有关更多信息,请参见此SO帖子:Firestore - Is It Possible To Get The ID Before It Was Added?